freshyo/apps/admin-ui/app/(drawer)/dashboard-banners/edit-banner/[id].tsx
2026-01-24 00:13:15 +05:30

163 lines
No EOL
4.6 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';
interface Banner {
id: number;
name: string;
imageUrl: string;
description?: string;
productIds?: number[];
redirectUrl?: string;
serialNum: number;
isActive: boolean;
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 [banner, setBanner] = useState<typeof bannerData>(undefined);
useEffect(() => {
const loadBanner = async () => {
try {
setIsLoading(true);
if (bannerData) {
// Handle data format compatibility (productId -> productIds migration)
const processedBanner = {
...bannerData,
productIds: Array.isArray(bannerData.productIds)
? bannerData.productIds
: (bannerData.productIds ? [bannerData.productIds] : [])
};
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 || '',
productIds: banner.productIds || [],
redirectUrl: banner.redirectUrl || '',
// serialNum removed - handled automatically by backend
} : {
name: '',
imageUrl: '',
description: '',
productIds: [],
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,
productIds: values.productIds.length > 0 ? values.productIds : [],
redirectUrl: values.redirectUrl || undefined,
});
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>
);
}