From ba479a671c2805b419fe3ac23215666cd2ab6f90 Mon Sep 17 00:00:00 2001 From: Ken Yasue Date: Tue, 25 Mar 2025 11:29:54 +0100 Subject: [PATCH] save work --- doc/prompts/11 Email template | 7 ++ src/app/(admin)/admin/layout.tsx | 6 + src/app/api/email-templates/[id]/route.ts | 122 +++++++++++++++++++++ src/app/api/email-templates/route.ts | 70 ++++++++++++ src/lib/database/config.ts | 7 +- src/lib/database/entities/EmailTemplate.ts | 19 ++++ src/lib/database/index.ts | 1 + 7 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 doc/prompts/11 Email template create mode 100644 src/app/api/email-templates/[id]/route.ts create mode 100644 src/app/api/email-templates/route.ts create mode 100644 src/lib/database/entities/EmailTemplate.ts 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';