diff --git a/doc/prompts/11. EmailTemplate CRUD b/doc/prompts/11. EmailTemplate CRUD new file mode 100644 index 0000000..03f593d --- /dev/null +++ b/doc/prompts/11. EmailTemplate CRUD @@ -0,0 +1,5 @@ +Please add model EmailTemplate and make CRUD UI in admin console. +ModelName: EmailTamplate +id, content, modifiedAt, createdAt + +create branch features/emailtemplate first and commit changes in the end \ No newline at end of file diff --git a/src/app/(admin)/admin/email-templates/DeleteButton.tsx b/src/app/(admin)/admin/email-templates/DeleteButton.tsx new file mode 100644 index 0000000..318e130 --- /dev/null +++ b/src/app/(admin)/admin/email-templates/DeleteButton.tsx @@ -0,0 +1,68 @@ +'use client'; + +import { useState } from 'react'; +import { useRouter } from 'next/navigation'; + +interface DeleteButtonProps { + templateId: string; +} + +export default function DeleteButton({ templateId }: DeleteButtonProps) { + const router = useRouter(); + const [isDeleting, setIsDeleting] = useState(false); + const [showConfirm, setShowConfirm] = useState(false); + + const handleDelete = async () => { + if (isDeleting) return; + + setIsDeleting(true); + try { + const response = await fetch(`/api/email-templates/${templateId}`, { + method: 'DELETE', + }); + + if (!response.ok) { + throw new Error('Failed to delete email template'); + } + + // Refresh the page to show updated list + router.refresh(); + } catch (error) { + console.error('Error deleting email template:', error); + alert('Failed to delete email template'); + } finally { + setIsDeleting(false); + setShowConfirm(false); + } + }; + + return ( + <> + {showConfirm ? ( + + + + + ) : ( + + )} + + ); +} diff --git a/src/app/(admin)/admin/email-templates/components/EditEmailTemplate.tsx b/src/app/(admin)/admin/email-templates/components/EditEmailTemplate.tsx new file mode 100644 index 0000000..33fe90f --- /dev/null +++ b/src/app/(admin)/admin/email-templates/components/EditEmailTemplate.tsx @@ -0,0 +1,169 @@ +'use client'; + +import { useState, useEffect, FormEvent, ChangeEvent } from 'react'; +import { useRouter } from 'next/navigation'; +import Link from 'next/link'; + +interface EmailTemplate { + id: string; + content: string; + createdAt: string; + modifiedAt: string; +} + +interface EditEmailTemplateProps { + id?: string; // Optional for new template +} + +export default function EditEmailTemplate({ id }: EditEmailTemplateProps) { + const router = useRouter(); + const [formData, setFormData] = useState({ + content: '', + }); + const [isLoading, setIsLoading] = useState(!!id); // Only loading if editing + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); + + // Fetch email template data if editing + useEffect(() => { + const fetchEmailTemplate = async () => { + if (!id) { + setIsLoading(false); + return; + } + + try { + const response = await fetch(`/api/email-templates/${id}`); + + if (!response.ok) { + throw new Error('Failed to fetch email template'); + } + + const template: EmailTemplate = await response.json(); + + setFormData({ + content: template.content, + }); + + setIsLoading(false); + } catch (err) { + setError('Failed to load email template data'); + setIsLoading(false); + } + }; + + fetchEmailTemplate(); + }, [id]); + + const handleChange = (e: ChangeEvent) => { + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + }; + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + setIsSubmitting(true); + setError(null); + + try { + // Validate form + if (!formData.content) { + throw new Error('Content is required'); + } + + // Determine if creating or updating + const url = id ? `/api/email-templates/${id}` : '/api/email-templates'; + const method = id ? 'PUT' : 'POST'; + + // Submit the form + const response = await fetch(url, { + method, + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }); + + if (!response.ok) { + const data = await response.json(); + throw new Error(data.error || `Failed to ${id ? 'update' : 'create'} email template`); + } + + // Redirect to email templates list on success + router.push('/admin/email-templates'); + router.refresh(); + } catch (err) { + setError(err instanceof Error ? err.message : 'An error occurred'); + setIsSubmitting(false); + } + }; + + if (isLoading) { + return
Loading...
; + } + + return ( +
+
+

+ {id ? 'Edit Email Template' : 'Add New Email Template'} +

+ + Back to Email Templates + +
+ + {error && ( +
+
+
+ + + +
+
+

{error}

+
+
+
+ )} + +
+
+ +