diff --git a/doc/prompts/11 Email template b/doc/prompts/11 Email template
new file mode 100644
index 0000000..ccfe1f1
--- /dev/null
+++ b/doc/prompts/11 Email template
@@ -0,0 +1,7 @@
+I want add EmailTemplate Model
+Tablename: EmailTemplate
+id, content, modifiedAt, createdAt
+
+Create branch features/emailtemplate
+Make CRUD operation UI in Admin console
+Then commit changes
\ No newline at end of file
diff --git a/src/app/(admin)/admin/layout.tsx b/src/app/(admin)/admin/layout.tsx
index ac85add..7247fa3 100644
--- a/src/app/(admin)/admin/layout.tsx
+++ b/src/app/(admin)/admin/layout.tsx
@@ -112,6 +112,12 @@ export default function RootLayout({
>
Contact Records
+
+ Email Templates
+
diff --git a/src/app/api/email-templates/[id]/route.ts b/src/app/api/email-templates/[id]/route.ts
new file mode 100644
index 0000000..edd8592
--- /dev/null
+++ b/src/app/api/email-templates/[id]/route.ts
@@ -0,0 +1,122 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { getDataSource, EmailTemplate } from '@/lib/database';
+
+// GET /api/email-templates/[id] - Get a single email template by ID
+export async function GET(
+ request: NextRequest,
+ { params }: { params: { id: string } }
+) {
+ try {
+ const { id } = params;
+ const dataSource = await getDataSource();
+ const emailTemplateRepository = dataSource.getRepository(EmailTemplate);
+
+ const emailTemplate = await emailTemplateRepository.findOne({
+ where: { id }
+ });
+
+ if (!emailTemplate) {
+ return NextResponse.json(
+ { error: 'Email template not found' },
+ { status: 404 }
+ );
+ }
+
+ return NextResponse.json(emailTemplate);
+ } catch (error) {
+ console.error('Error fetching email template:', error);
+ return NextResponse.json(
+ { error: 'Failed to fetch email template' },
+ { status: 500 }
+ );
+ }
+}
+
+// PUT /api/email-templates/[id] - Update an email template
+export async function PUT(
+ request: NextRequest,
+ { params }: { params: { id: string } }
+) {
+ try {
+ const { id } = params;
+ const dataSource = await getDataSource();
+ const emailTemplateRepository = dataSource.getRepository(EmailTemplate);
+
+ // Check if email template exists
+ const emailTemplate = await emailTemplateRepository.findOne({
+ where: { id }
+ });
+
+ if (!emailTemplate) {
+ return NextResponse.json(
+ { error: 'Email template not found' },
+ { status: 404 }
+ );
+ }
+
+ // Get update data
+ const data = await request.json();
+ const { name, content } = data;
+
+ // Validate required fields
+ if (!name && !content) {
+ return NextResponse.json(
+ { error: 'At least one field (name or content) must be provided' },
+ { status: 400 }
+ );
+ }
+
+ // Update fields
+ if (name) emailTemplate.name = name;
+ if (content) emailTemplate.content = content;
+
+ // Save updated email template
+ const updatedEmailTemplate = await emailTemplateRepository.save(emailTemplate);
+
+ return NextResponse.json(updatedEmailTemplate);
+ } catch (error) {
+ console.error('Error updating email template:', error);
+ return NextResponse.json(
+ { error: 'Failed to update email template' },
+ { status: 500 }
+ );
+ }
+}
+
+// DELETE /api/email-templates/[id] - Delete an email template
+export async function DELETE(
+ request: NextRequest,
+ { params }: { params: { id: string } }
+) {
+ try {
+ const { id } = params;
+ const dataSource = await getDataSource();
+ const emailTemplateRepository = dataSource.getRepository(EmailTemplate);
+
+ // Check if email template exists
+ const emailTemplate = await emailTemplateRepository.findOne({
+ where: { id }
+ });
+
+ if (!emailTemplate) {
+ return NextResponse.json(
+ { error: 'Email template not found' },
+ { status: 404 }
+ );
+ }
+
+ // Delete the email template
+ await emailTemplateRepository.remove(emailTemplate);
+
+ return NextResponse.json(
+ { message: 'Email template deleted successfully' },
+ { status: 200 }
+ );
+ } catch (error) {
+ console.error('Error deleting email template:', error);
+ return NextResponse.json(
+ { error: 'Failed to delete email template' },
+ { status: 500 }
+ );
+ }
+}
diff --git a/src/app/api/email-templates/route.ts b/src/app/api/email-templates/route.ts
new file mode 100644
index 0000000..858119b
--- /dev/null
+++ b/src/app/api/email-templates/route.ts
@@ -0,0 +1,70 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { getDataSource, EmailTemplate } from '@/lib/database';
+
+// GET /api/email-templates - Get all email templates
+export async function GET(request: NextRequest) {
+ try {
+ const dataSource = await getDataSource();
+ const emailTemplateRepository = dataSource.getRepository(EmailTemplate);
+
+ // Get query parameters
+ const url = new URL(request.url);
+ const search = url.searchParams.get('search');
+
+ // Build query
+ const queryOptions: any = {
+ order: { createdAt: 'DESC' }
+ };
+
+ // Add search filter if provided
+ if (search) {
+ queryOptions.where = [
+ { name: search ? { contains: search } : undefined }
+ ];
+ }
+
+ const emailTemplates = await emailTemplateRepository.find(queryOptions);
+
+ return NextResponse.json(emailTemplates);
+ } catch (error) {
+ console.error('Error fetching email templates:', error);
+ return NextResponse.json(
+ { error: 'Failed to fetch email templates' },
+ { status: 500 }
+ );
+ }
+}
+
+// POST /api/email-templates - Create a new email template
+export async function POST(request: NextRequest) {
+ try {
+ const dataSource = await getDataSource();
+ const emailTemplateRepository = dataSource.getRepository(EmailTemplate);
+
+ const data = await request.json();
+ const { name, content } = data;
+
+ // Validate required fields
+ if (!name || !content) {
+ return NextResponse.json(
+ { error: 'Name and content are required' },
+ { status: 400 }
+ );
+ }
+
+ // Create and save the new email template
+ const emailTemplate = new EmailTemplate();
+ emailTemplate.name = name;
+ emailTemplate.content = content;
+
+ const savedEmailTemplate = await emailTemplateRepository.save(emailTemplate);
+
+ return NextResponse.json(savedEmailTemplate, { status: 201 });
+ } catch (error) {
+ console.error('Error creating email template:', error);
+ return NextResponse.json(
+ { error: 'Failed to create email template' },
+ { status: 500 }
+ );
+ }
+}
diff --git a/src/lib/database/config.ts b/src/lib/database/config.ts
index 52b3191..71d423a 100644
--- a/src/lib/database/config.ts
+++ b/src/lib/database/config.ts
@@ -3,13 +3,14 @@ import { User } from './entities/User';
import { Post } from './entities/Post';
import { Customer } from './entities/Customer';
import { ContactRecord } from './entities/ContactRecord';
+import { EmailTemplate } from './entities/EmailTemplate';
import path from 'path';
// Default configuration for SQLite (development/testing)
const sqliteConfig: DataSourceOptions = {
type: 'sqlite',
database: path.join(process.cwd(), 'data', 'database.sqlite'),
- entities: [User, Post, Customer, ContactRecord],
+ entities: [User, Post, Customer, ContactRecord, EmailTemplate],
synchronize: true, // Set to false in production
logging: process.env.NODE_ENV === 'development',
};
@@ -22,7 +23,7 @@ const mysqlConfig: DataSourceOptions = {
username: process.env.DB_USERNAME || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_DATABASE || 'kantancms',
- entities: [User, Post, Customer, ContactRecord],
+ entities: [User, Post, Customer, ContactRecord, EmailTemplate],
synchronize: false, // Always false in production
logging: process.env.NODE_ENV === 'development',
};
@@ -35,7 +36,7 @@ const postgresConfig: DataSourceOptions = {
username: process.env.DB_USERNAME || 'postgres',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_DATABASE || 'kantancms',
- entities: [User, Post, Customer, ContactRecord],
+ entities: [User, Post, Customer, ContactRecord, EmailTemplate],
synchronize: false, // Always false in production
logging: process.env.NODE_ENV === 'development',
};
diff --git a/src/lib/database/entities/EmailTemplate.ts b/src/lib/database/entities/EmailTemplate.ts
new file mode 100644
index 0000000..848db49
--- /dev/null
+++ b/src/lib/database/entities/EmailTemplate.ts
@@ -0,0 +1,19 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
+
+@Entity('email_templates')
+export class EmailTemplate {
+ @PrimaryGeneratedColumn('uuid')
+ id: string;
+
+ @Column()
+ name: string;
+
+ @Column('text')
+ content: string;
+
+ @CreateDateColumn()
+ createdAt: Date;
+
+ @UpdateDateColumn()
+ modifiedAt: Date;
+}
diff --git a/src/lib/database/index.ts b/src/lib/database/index.ts
index 6430f2f..ad0d33a 100644
--- a/src/lib/database/index.ts
+++ b/src/lib/database/index.ts
@@ -36,3 +36,4 @@ export * from './entities/User';
export * from './entities/Post';
export * from './entities/Customer';
export * from './entities/ContactRecord';
+export * from './entities/EmailTemplate';