返回 presentation-ai
font-pair-actions.ts
根目录 / src / app / _actions / presentation / font-pair-actions.ts
1 "use server";
2
3 import { utapi } from "@/app/api/uploadthing/core";
4 import { auth } from "@/server/auth";
5 import { db } from "@/server/db";
6 import * as z from "zod";
7
8 // Schema for creating a font pair
9 const fontPairSchema = z.object({
10 heading: z.string().min(1),
11 headingUrl: z.string().optional(),
12 headingWeight: z.number().optional(),
13 body: z.string().min(1),
14 bodyUrl: z.string().optional(),
15 bodyWeight: z.number().optional(),
16 });
17
18 export type FontPairFormData = z.infer<typeof fontPairSchema>;
19
20 // Create a new font pair
21 export async function createFontPair(formData: FontPairFormData) {
22 try {
23 const session = await auth();
24 if (!session?.user) {
25 return {
26 success: false,
27 message: "You must be signed in to save a font pair",
28 };
29 }
30
31 const validatedData = fontPairSchema.parse(formData);
32
33 const newFontPair = await db.fontPair.create({
34 data: {
35 heading: validatedData.heading,
36 headingUrl: validatedData.headingUrl,
37 headingWeight: validatedData.headingWeight,
38 body: validatedData.body,
39 bodyUrl: validatedData.bodyUrl,
40 bodyWeight: validatedData.bodyWeight,
41 userId: session.user.id,
42 },
43 });
44
45 return {
46 success: true,
47 fontPairId: newFontPair.id,
48 message: "Font pair saved successfully",
49 };
50 } catch (error) {
51 console.error("Failed to create font pair:", error);
52
53 if (error instanceof z.ZodError) {
54 return {
55 success: false,
56 message:
57 "Invalid font pair data. Please check your inputs and try again.",
58 };
59 } else if (error instanceof Error && error.message.includes("Prisma")) {
60 return {
61 success: false,
62 message: "Database error. Please try again later.",
63 };
64 } else {
65 return {
66 success: false,
67 message: "Something went wrong. Please try again later.",
68 };
69 }
70 }
71 }
72
73 // Get all font pairs for the current user
74 export async function getUserFontPairs() {
75 try {
76 const session = await auth();
77 if (!session?.user) {
78 return {
79 success: false,
80 message: "You must be signed in to view your font pairs",
81 fontPairs: [],
82 };
83 }
84
85 const fontPairs = await db.fontPair.findMany({
86 where: {
87 userId: session.user.id,
88 },
89 orderBy: {
90 createdAt: "desc",
91 },
92 });
93
94 return {
95 success: true,
96 fontPairs,
97 };
98 } catch (error) {
99 console.error("Failed to fetch font pairs:", error);
100 return {
101 success: false,
102 message:
103 "Unable to load font pairs at this time. Please try again later.",
104 fontPairs: [],
105 };
106 }
107 }
108
109 // Delete a font pair
110 export async function deleteFontPair(fontPairId: string) {
111 try {
112 const session = await auth();
113 if (!session?.user) {
114 return {
115 success: false,
116 message: "You must be signed in to delete a font pair",
117 };
118 }
119
120 // Verify ownership
121 const existingFontPair = await db.fontPair.findUnique({
122 where: { id: fontPairId },
123 });
124
125 if (!existingFontPair) {
126 return { success: false, message: "Font pair not found" };
127 }
128
129 if (existingFontPair.userId !== session.user.id) {
130 return {
131 success: false,
132 message: "Not authorized to delete this font pair",
133 };
134 }
135
136 // Delete files from UploadThing if they exist
137 const filesToDelete: string[] = [];
138
139 if (existingFontPair.headingUrl) {
140 const headingKey = existingFontPair.headingUrl.split("/").pop();
141 if (headingKey) filesToDelete.push(headingKey);
142 }
143
144 if (existingFontPair.bodyUrl) {
145 const bodyKey = existingFontPair.bodyUrl.split("/").pop();
146 if (bodyKey) filesToDelete.push(bodyKey);
147 }
148
149 if (filesToDelete.length > 0) {
150 try {
151 await utapi.deleteFiles(filesToDelete);
152 } catch (error) {
153 console.error("Failed to delete font files from UploadThing:", error);
154 // Continue with database deletion even if file deletion fails
155 }
156 }
157
158 await db.fontPair.delete({
159 where: { id: fontPairId },
160 });
161
162 return {
163 success: true,
164 message: "Font pair deleted successfully",
165 };
166 } catch (error) {
167 console.error("Failed to delete font pair:", error);
168 return {
169 success: false,
170 message:
171 "Something went wrong while deleting the font pair. Please try again later.",
172 };
173 }
174 }
175
175 lines TYPESCRIPT