freshyo/apps/admin-ui/app/(drawer)/dashboard/dashboard-banners/edit/[id].tsx
2026-09-06 18:05:20 +05:30

168 lines
4.9 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { View, TouchableOpacity, Alert } from 'react-native';
import { AppContainer, MyText, tw } from 'common-ui';
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import { useRouter, useLocalSearchParams } from 'expo-router';
import { FormikHelpers } from 'formik';
import BannerForm, { BannerFormData } from '@/components/BannerForm';
import { trpc } from '@/src/trpc-client';
import type { Banner as SharedBanner } from '@packages/shared';
// Form/hardened view of the shared banner (string dates, non-null editable fields)
type Banner = Omit<
SharedBanner,
'description' | 'skuIds' | 'redirectUrl' | 'serialNum' | 'createdAt' | 'lastUpdated'
> & {
description?: string;
skuIds?: number[];
redirectUrl?: string;
serialNum: number;
createdAt: string;
lastUpdated: string;
};
export default function EditBanner() {
const router = useRouter();
const { id } = useLocalSearchParams();
const bannerId = id as string;
const [isLoading, setIsLoading] = useState(true);
const [isSubmitting, setIsSubmitting] = useState(false);
// Load real banner data from API
const {data: bannerData } = trpc.admin.banner.getBanner.useQuery({
id: parseInt(bannerId)
});
const { refetch: refetchBanners } = trpc.admin.banner.getBanners.useQuery(undefined, {
enabled: false,
});
const [banner, setBanner] = useState<typeof bannerData>(undefined);
useEffect(() => {
const loadBanner = async () => {
try {
setIsLoading(true);
if (bannerData) {
// Handle data format compatibility (productId -> skuIds migration)
const processedBanner = {
...bannerData,
skuIds: Array.isArray(bannerData.skuIds)
? bannerData.skuIds
: (bannerData.skuIds ? [bannerData.skuIds] : [])
};
setBanner(processedBanner);
} else {
Alert.alert('Error', 'Banner not found');
router.back();
}
} catch (error) {
console.error('Failed to load banner:', error);
Alert.alert('Error', 'Failed to load banner data');
router.back();
} finally {
setIsLoading(false);
}
};
loadBanner();
}, [bannerId, bannerData]);
const initialValues: BannerFormData = banner ? {
name: banner.name,
imageUrl: banner.imageUrl,
description: banner.description || '',
skuIds: banner.skuIds || [],
redirectUrl: banner.redirectUrl || '',
// serialNum removed - handled automatically by backend
} : {
name: '',
imageUrl: '',
description: '',
skuIds: [],
redirectUrl: '',
// serialNum removed - handled automatically by backend
};
const updateBannerMutation = trpc.admin.banner.updateBanner.useMutation();
const handleSubmit = async (values: BannerFormData, imageUrl?: string) => {
if (!banner) return;
setIsSubmitting(true);
try {
await updateBannerMutation.mutateAsync({
id: banner.id,
name: values.name,
imageUrl: imageUrl || banner.imageUrl,
description: values.description || undefined,
skuIds: values.skuIds.length > 0 ? values.skuIds : [],
redirectUrl: values.redirectUrl || undefined,
});
await refetchBanners()
Alert.alert('Success', 'Banner updated successfully', [
{
text: 'OK',
onPress: () => router.back(),
}
]);
} catch (error) {
Alert.alert('Error', 'Failed to update banner. Please try again.');
} finally {
setIsSubmitting(false);
}
};
const handleCancel = () => {
router.back();
};
if (isLoading) {
return (
<AppContainer>
<View style={tw`flex-1 justify-center items-center bg-white`}>
<MyText style={tw`text-gray-600`}>Loading banner...</MyText>
</View>
</AppContainer>
);
}
if (!banner) {
return (
<AppContainer>
<View style={tw`flex-1 justify-center items-center bg-white`}>
<MyText style={tw`text-red-600`}>Banner not found</MyText>
</View>
</AppContainer>
);
}
return (
<AppContainer>
<View style={tw`flex-1 bg-white`}>
{/* Header */}
<View style={tw`flex-row items-center justify-between px-6 py-4 border-b border-gray-200`}>
<TouchableOpacity onPress={handleCancel} style={tw`p-2`}>
<MaterialIcons name="arrow-back" size={24} color="#374151" />
</TouchableOpacity>
<MyText style={tw`text-xl font-bold text-gray-900`}>Edit Banner</MyText>
<View style={tw`w-10`} />
</View>
<BannerForm
initialValues={initialValues}
onSubmit={handleSubmit}
onCancel={handleCancel}
submitButtonText="Update Banner"
isSubmitting={isSubmitting}
existingImageUrl={banner.imageUrl}
/>
</View>
</AppContainer>
);
}