@devvistatech/devvista-kit 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -12
- package/LICENSE +6 -6
- package/README.md +15 -15
- package/app/about/page.tsx +298 -298
- package/app/adRequest/page.tsx +549 -549
- package/app/analytics/page.tsx +346 -346
- package/app/api/about/route.ts +306 -306
- package/app/api/adRequest/route.ts +567 -567
- package/app/api/analytics/[reportType]/route.ts +337 -337
- package/app/api/bio/route.ts +313 -313
- package/app/api/blog/route.ts +306 -306
- package/app/api/chat/route.ts +14 -14
- package/app/api/contact/route.ts +409 -409
- package/app/api/contacts/route.ts +224 -224
- package/app/api/files/route.ts +429 -429
- package/app/api/gallery-data/route.ts +735 -735
- package/app/api/schedule/route.ts +455 -455
- package/app/api/sync-user/route.ts +131 -131
- package/app/api/trial-request/route.ts +297 -297
- package/app/blog/[id]/page.tsx +288 -288
- package/app/blog/page.tsx +216 -216
- package/app/contact/page.tsx +284 -284
- package/app/faq/page.tsx +191 -191
- package/app/gallery/page.tsx +315 -315
- package/app/globals.css +58 -58
- package/app/layout.tsx +110 -110
- package/app/not-found.tsx +20 -20
- package/app/page.tsx +338 -338
- package/app/schedule/page.tsx +660 -660
- package/bin/init.js +219 -219
- package/components/addOns/functional/BioEditor.tsx +446 -446
- package/components/addOns/functional/CalendlyWidget.tsx +107 -107
- package/components/addOns/functional/ClassList.tsx +145 -145
- package/components/addOns/functional/ClassPopup.tsx +398 -398
- package/components/addOns/functional/ContactForm.tsx +284 -284
- package/components/addOns/functional/FileUploader.tsx +294 -294
- package/components/addOns/functional/ImageDescCarousel.tsx +730 -730
- package/components/addOns/functional/NewUserAnalytics.tsx +100 -100
- package/components/addOns/functional/ScheduleCarousel.tsx +171 -171
- package/components/addOns/functional/aboutSections/AboutSection.tsx +544 -544
- package/components/addOns/functional/aboutSections/constants/aboutSection.ts +65 -65
- package/components/addOns/functional/blogSections/BlogDashboard.tsx +184 -184
- package/components/addOns/functional/blogSections/BlogFormPopUp.tsx +554 -554
- package/components/addOns/functional/blogSections/BlogList.tsx +148 -148
- package/components/addOns/functional/blogSections/BlogSidebar.tsx +58 -58
- package/components/addOns/functional/blogSections/constants/blogDashboard.ts +28 -28
- package/components/addOns/functional/blogSections/constants/blogFormPopUp.ts +97 -97
- package/components/addOns/functional/blogSections/constants/blogList.ts +22 -22
- package/components/addOns/functional/blogSections/constants/blogSidebar.ts +15 -15
- package/components/addOns/functional/contactsDashboard/ContactsDashboard.tsx +366 -366
- package/components/addOns/functional/contactsDashboard/constants/contactsDashboard.ts +70 -70
- package/components/addOns/functional/galleries/GalleryComplex.tsx +836 -836
- package/components/addOns/functional/galleries/GallerySimple.tsx +509 -509
- package/components/addOns/functional/galleries/constants/galleryComplex.ts +106 -106
- package/components/addOns/functional/galleries/constants/gallerySimple.ts +76 -76
- package/components/addOns/functional/schedules/ScheduleGridOne.tsx +262 -262
- package/components/addOns/functional/schedules/ScheduleGridTwo.tsx +294 -294
- package/components/addOns/functional/schedules/ScheduleGridTwoBasic.tsx +288 -288
- package/components/addOns/functional/schedules/SchedulerForm.tsx +428 -428
- package/components/addOns/functional/schedules/constants/ScheduleGridTwo.ts +40 -40
- package/components/addOns/functional/schedules/constants/ScheduleGridTwoBasic.ts +40 -40
- package/components/addOns/functional/schedules/constants/SchedulerForm.ts +65 -65
- package/components/addOns/functional/schedules/constants/scheduleGridOne.ts +54 -54
- package/components/addOns/non-functional/AnnouncementBanner.tsx +46 -46
- package/components/addOns/non-functional/FeaturesSection.tsx +62 -62
- package/components/addOns/non-functional/Heros/HeroSection.tsx +142 -142
- package/components/addOns/non-functional/IconBubble.tsx +49 -49
- package/components/addOns/non-functional/SampleCarousel.tsx +204 -204
- package/components/addOns/non-functional/Testimonials.tsx +334 -334
- package/components/addOns/non-functional/ThreeSetGallery.tsx +63 -63
- package/components/addOns/non-functional/aboutSections/AboutSection.tsx +62 -62
- package/components/addOns/non-functional/aboutSections/constants/aboutSection.ts +24 -24
- package/components/addOns/non-functional/imageCarousels/ProductSlider.tsx +117 -117
- package/components/addOns/non-functional/imageCarousels/ProgramCarousel.tsx +232 -232
- package/components/addOns/non-functional/imageCarousels/constants/programCarousel.ts +39 -39
- package/components/addOns/non-functional/imageCarousels/constants/programSlider.ts +36 -36
- package/components/addOns/non-functional/spinner.tsx +21 -21
- package/components/footers/footer.tsx +453 -453
- package/components/navBars/navbar.tsx +310 -310
- package/components/other/accordion.tsx +58 -58
- package/components/other/admin-menu.tsx +68 -68
- package/components/other/alert-dialog.tsx +141 -141
- package/components/other/alert.tsx +59 -59
- package/components/other/aspect-ratio.tsx +7 -7
- package/components/other/avatar.tsx +50 -50
- package/components/other/badge.tsx +36 -36
- package/components/other/breadcrumb.tsx +115 -115
- package/components/other/button.tsx +738 -738
- package/components/other/calendar.tsx +66 -66
- package/components/other/card.tsx +86 -86
- package/components/other/carousel.tsx +274 -274
- package/components/other/chart.tsx +363 -363
- package/components/other/checkbox.tsx +30 -30
- package/components/other/collapsible.tsx +11 -11
- package/components/other/command.tsx +155 -155
- package/components/other/context-menu.tsx +200 -200
- package/components/other/dialog.tsx +122 -122
- package/components/other/drawer.tsx +118 -118
- package/components/other/dropdown-menu.tsx +200 -200
- package/components/other/form.tsx +179 -179
- package/components/other/hover-card.tsx +29 -29
- package/components/other/input-otp.tsx +71 -71
- package/components/other/input.tsx +25 -25
- package/components/other/label.tsx +26 -26
- package/components/other/menubar.tsx +236 -236
- package/components/other/mobile-icon.tsx +21 -21
- package/components/other/navigation-menu.tsx +128 -128
- package/components/other/pagination.tsx +117 -117
- package/components/other/popover.tsx +31 -31
- package/components/other/progress.tsx +28 -28
- package/components/other/radio-group.tsx +44 -44
- package/components/other/resizable.tsx +45 -45
- package/components/other/scroll-area.tsx +48 -48
- package/components/other/select.tsx +160 -160
- package/components/other/separator.tsx +31 -31
- package/components/other/sheet.tsx +140 -140
- package/components/other/skeleton.tsx +15 -15
- package/components/other/slider.tsx +28 -28
- package/components/other/social-icons.tsx +39 -39
- package/components/other/sonner.tsx +31 -31
- package/components/other/switch.tsx +29 -29
- package/components/other/table.tsx +117 -117
- package/components/other/tabs.tsx +55 -55
- package/components/other/textarea.tsx +24 -24
- package/components/other/toast.tsx +122 -122
- package/components/other/toaster.tsx +35 -35
- package/components/other/toggle-group.tsx +61 -61
- package/components/other/toggle.tsx +45 -45
- package/components/other/tooltip.tsx +30 -30
- package/components/theme-provider.tsx +8 -8
- package/components/types.ts +49 -49
- package/dist/.next/types/app/api/about/route.js +52 -0
- package/dist/.next/types/app/api/blog/route.js +52 -0
- package/dist/.next/types/app/api/files/route.js +52 -0
- package/dist/.next/types/app/api/schedule/route.js +52 -0
- package/dist/.next/types/app/api/sync-user/route.js +52 -0
- package/dist/.next/types/app/layout.js +22 -0
- package/dist/.next/types/app/page.js +22 -0
- package/dist/app/about/page.jsx +258 -0
- package/dist/app/adRequest/page.jsx +531 -0
- package/dist/app/analytics/page.jsx +298 -0
- package/dist/app/api/about/route.js +285 -0
- package/dist/app/api/adRequest/route.js +440 -0
- package/dist/app/api/analytics/[reportType]/route.js +357 -0
- package/dist/app/api/bio/route.js +293 -0
- package/dist/app/api/blog/route.js +366 -0
- package/dist/app/api/chat/route.js +58 -0
- package/dist/app/api/contact/route.js +163 -0
- package/dist/app/api/contacts/route.js +234 -0
- package/dist/app/api/files/route.js +444 -0
- package/dist/app/api/gallery-data/route.js +719 -0
- package/dist/app/api/schedule/route.js +461 -0
- package/dist/app/api/sync-user/route.js +186 -0
- package/dist/app/api/trial-request/route.js +165 -0
- package/dist/app/blog/[id]/page.jsx +312 -0
- package/dist/app/blog/page.jsx +210 -0
- package/dist/app/constants/about.js +32 -0
- package/dist/app/constants/adRequest.js +113 -0
- package/dist/app/constants/contact.js +40 -0
- package/dist/app/constants/faq.js +36 -0
- package/dist/app/constants/gallery.js +42 -0
- package/dist/app/constants/page.js +69 -0
- package/dist/app/constants/schedule.js +71 -0
- package/dist/app/contact/page.jsx +119 -0
- package/dist/app/faq/page.jsx +97 -0
- package/dist/app/gallery/page.jsx +281 -0
- package/dist/app/layout.jsx +45 -0
- package/dist/app/not-found.jsx +14 -0
- package/dist/app/page.jsx +324 -0
- package/dist/app/schedule/page.jsx +500 -0
- package/dist/components/addOns/functional/BioEditor.jsx +187 -0
- package/dist/components/addOns/functional/CalendlyWidget.jsx +61 -0
- package/dist/components/addOns/functional/ClassList.jsx +158 -0
- package/dist/components/addOns/functional/ClassPopup.jsx +300 -0
- package/dist/components/addOns/functional/ContactForm.jsx +219 -0
- package/dist/components/addOns/functional/FileUploader.jsx +222 -0
- package/dist/components/addOns/functional/ImageDescCarousel.jsx +491 -0
- package/dist/components/addOns/functional/NewUserAnalytics.jsx +71 -0
- package/dist/components/addOns/functional/ScheduleCarousel.jsx +68 -0
- package/dist/components/addOns/functional/aboutSections/AboutSection.jsx +372 -0
- package/dist/components/addOns/functional/aboutSections/constants/aboutSection.js +65 -0
- package/dist/components/addOns/functional/blogSections/BlogDashboard.jsx +111 -0
- package/dist/components/addOns/functional/blogSections/BlogFormPopUp.jsx +465 -0
- package/dist/components/addOns/functional/blogSections/BlogList.jsx +170 -0
- package/dist/components/addOns/functional/blogSections/BlogSidebar.jsx +35 -0
- package/dist/components/addOns/functional/blogSections/constants/blogDashboard.js +28 -0
- package/dist/components/addOns/functional/blogSections/constants/blogFormPopUp.js +97 -0
- package/dist/components/addOns/functional/blogSections/constants/blogList.js +22 -0
- package/dist/components/addOns/functional/blogSections/constants/blogSidebar.js +15 -0
- package/dist/components/addOns/functional/contactsDashboard/ContactsDashboard.jsx +355 -0
- package/dist/components/addOns/functional/contactsDashboard/constants/contactsDashboard.js +70 -0
- package/dist/components/addOns/functional/galleries/GalleryComplex.jsx +605 -0
- package/dist/components/addOns/functional/galleries/GallerySimple.jsx +363 -0
- package/dist/components/addOns/functional/galleries/constants/galleryComplex.js +106 -0
- package/dist/components/addOns/functional/galleries/constants/gallerySimple.js +76 -0
- package/dist/components/addOns/functional/schedules/ScheduleGridOne.jsx +167 -0
- package/dist/components/addOns/functional/schedules/ScheduleGridTwo.jsx +100 -0
- package/dist/components/addOns/functional/schedules/ScheduleGridTwoBasic.jsx +97 -0
- package/dist/components/addOns/functional/schedules/SchedulerForm.jsx +188 -0
- package/dist/components/addOns/functional/schedules/constants/ScheduleGridTwo.js +40 -0
- package/dist/components/addOns/functional/schedules/constants/ScheduleGridTwoBasic.js +40 -0
- package/dist/components/addOns/functional/schedules/constants/SchedulerForm.js +65 -0
- package/dist/components/addOns/functional/schedules/constants/scheduleGridOne.js +54 -0
- package/dist/components/addOns/non-functional/AnnouncementBanner.jsx +24 -0
- package/dist/components/addOns/non-functional/FeaturesSection.jsx +38 -0
- package/dist/components/addOns/non-functional/HeroSection.jsx +71 -0
- package/dist/components/addOns/non-functional/Heros/HeroSection.jsx +71 -0
- package/dist/components/addOns/non-functional/IconBubble.jsx +36 -0
- package/dist/components/addOns/non-functional/SampleCarousel.jsx +114 -0
- package/dist/components/addOns/non-functional/Testimonials.jsx +177 -0
- package/dist/components/addOns/non-functional/ThreeSetGallery.jsx +40 -0
- package/dist/components/addOns/non-functional/aboutSections/AboutSection.jsx +35 -0
- package/dist/components/addOns/non-functional/aboutSections/constants/aboutSection.js +24 -0
- package/dist/components/addOns/non-functional/imageCarousels/ProductSlider.jsx +80 -0
- package/dist/components/addOns/non-functional/imageCarousels/ProgramCarousel.jsx +155 -0
- package/dist/components/addOns/non-functional/imageCarousels/constants/programCarousel.js +39 -0
- package/dist/components/addOns/non-functional/imageCarousels/constants/programSlider.js +36 -0
- package/dist/components/addOns/non-functional/spinner.jsx +13 -0
- package/dist/components/footers/footer.jsx +217 -0
- package/dist/components/navBars/navbar.jsx +159 -0
- package/dist/components/other/accordion.jsx +40 -0
- package/dist/components/other/admin-menu.jsx +34 -0
- package/dist/components/other/alert-dialog.jsx +64 -0
- package/dist/components/other/alert.jsx +41 -0
- package/dist/components/other/aspect-ratio.jsx +4 -0
- package/dist/components/other/avatar.jsx +31 -0
- package/dist/components/other/badge.jsx +32 -0
- package/dist/components/other/breadcrumb.jsx +57 -0
- package/dist/components/other/button.jsx +322 -0
- package/dist/components/other/calendar.jsx +43 -0
- package/dist/components/other/card.jsx +44 -0
- package/dist/components/other/carousel.jsx +140 -0
- package/dist/components/other/chart.jsx +182 -0
- package/dist/components/other/checkbox.jsx +26 -0
- package/dist/components/other/collapsible.jsx +6 -0
- package/dist/components/other/command.jsx +68 -0
- package/dist/components/other/context-menu.jsx +88 -0
- package/dist/components/other/dialog.jsx +60 -0
- package/dist/components/other/drawer.jsx +60 -0
- package/dist/components/other/dropdown-menu.jsx +90 -0
- package/dist/components/other/form.jsx +89 -0
- package/dist/components/other/hover-card.jsx +23 -0
- package/dist/components/other/input-otp.jsx +46 -0
- package/dist/components/other/input.jsx +19 -0
- package/dist/components/other/label.jsx +23 -0
- package/dist/components/other/login-popup.jsx +1 -0
- package/dist/components/other/menubar.jsx +96 -0
- package/dist/components/other/mobile-icon.jsx +11 -0
- package/dist/components/other/navigation-menu.jsx +62 -0
- package/dist/components/other/pagination.jsx +63 -0
- package/dist/components/other/popover.jsx +25 -0
- package/dist/components/other/progress.jsx +23 -0
- package/dist/components/other/radio-group.jsx +31 -0
- package/dist/components/other/resizable.jsx +29 -0
- package/dist/components/other/scroll-area.jsx +36 -0
- package/dist/components/other/select.jsx +83 -0
- package/dist/components/other/separator.jsx +21 -0
- package/dist/components/other/sheet.jsx +74 -0
- package/dist/components/other/signup-popup.jsx +1 -0
- package/dist/components/other/skeleton.jsx +17 -0
- package/dist/components/other/slider.jsx +26 -0
- package/dist/components/other/social-icons.jsx +15 -0
- package/dist/components/other/sonner.jsx +27 -0
- package/dist/components/other/switch.jsx +23 -0
- package/dist/components/other/table.jsx +56 -0
- package/dist/components/other/tabs.jsx +32 -0
- package/dist/components/other/textarea.jsx +19 -0
- package/dist/components/other/toast.jsx +58 -0
- package/dist/components/other/toaster.jsx +31 -0
- package/dist/components/other/toggle-group.jsx +41 -0
- package/dist/components/other/toggle.jsx +39 -0
- package/dist/components/other/tooltip.jsx +24 -0
- package/dist/components/theme-provider.jsx +18 -0
- package/dist/components/types.js +1 -0
- package/dist/hooks/use-toast.js +135 -0
- package/dist/lib/auth-context.jsx +144 -0
- package/dist/lib/constants/about.js +32 -0
- package/dist/lib/constants/adRequest.js +113 -0
- package/dist/lib/constants/contact.js +40 -0
- package/dist/lib/constants/faq.js +36 -0
- package/dist/lib/constants/gallery.js +42 -0
- package/dist/lib/constants/page.js +69 -0
- package/dist/lib/constants/schedule.js +71 -0
- package/dist/lib/google-analytics.jsx +148 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/verify-user.js +142 -0
- package/dist/middleware.js +37 -0
- package/dist/tailwind.config.js +86 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/hooks/use-toast.ts +188 -188
- package/lib/auth-context.tsx +130 -130
- package/lib/constants/about.ts +34 -34
- package/lib/constants/adRequest.ts +113 -113
- package/lib/constants/contact.ts +40 -40
- package/lib/constants/faq.ts +34 -21
- package/lib/constants/gallery.ts +42 -42
- package/lib/constants/page.ts +69 -69
- package/lib/constants/schedule.ts +71 -71
- package/lib/google-analytics.tsx +97 -97
- package/lib/verify-user.ts +117 -117
- package/middleware.ts +42 -42
- package/netlify.toml +5 -5
- package/next.config.js +10 -10
- package/package.json +115 -115
- package/tailwind.config.ts +89 -89
- package/tsconfig.json +23 -23
package/app/api/blog/route.ts
CHANGED
|
@@ -1,307 +1,307 @@
|
|
|
1
|
-
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
-
import { getAuth } from "@clerk/nextjs/server";
|
|
3
|
-
|
|
4
|
-
interface StrapiUser {
|
|
5
|
-
id: number;
|
|
6
|
-
username: string;
|
|
7
|
-
email: string;
|
|
8
|
-
businessAdminId?: string;
|
|
9
|
-
firstName?: string;
|
|
10
|
-
lastName?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface BlogPost {
|
|
14
|
-
id: number;
|
|
15
|
-
documentId: string;
|
|
16
|
-
title: string;
|
|
17
|
-
description: string;
|
|
18
|
-
author: string;
|
|
19
|
-
publishedAt: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const BLOG_API_URL = process.env.STRAPI_BLOG_API_URL || "";
|
|
23
|
-
const STRAPI_USER_LIST_API_URL = process.env.STRAPI_USER_LIST_API_URL || "";
|
|
24
|
-
const ADMIN_BUSINESS_ID = process.env.ADMIN_BUSINESS_ID || "";
|
|
25
|
-
const STRAPI_API_TOKEN = process.env.STRAPI_API_TOKEN || "";
|
|
26
|
-
|
|
27
|
-
async function verifyUser(userId: string): Promise<StrapiUser | null> {
|
|
28
|
-
try {
|
|
29
|
-
const response = await fetch(
|
|
30
|
-
`${STRAPI_USER_LIST_API_URL}?filters[authId][$eq]=${userId}`,
|
|
31
|
-
{
|
|
32
|
-
headers: {
|
|
33
|
-
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
34
|
-
"Content-Type": "application/json",
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
if (!response.ok) {
|
|
40
|
-
console.error("User verification failed:", response.status);
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const userData = await response.json();
|
|
45
|
-
const strapiUser = userData.data?.find((user: any) => user.authId === userId);
|
|
46
|
-
if (!strapiUser) return null;
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
id: strapiUser.id,
|
|
50
|
-
username: strapiUser.username,
|
|
51
|
-
email: strapiUser.email,
|
|
52
|
-
businessAdminId: strapiUser.businessAdminId,
|
|
53
|
-
firstName: strapiUser.firstName,
|
|
54
|
-
lastName: strapiUser.lastName,
|
|
55
|
-
};
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error("Error verifying user:", error);
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async function getBlogPosts(userId: string | null, isAdmin: boolean): Promise<BlogPost[]> {
|
|
63
|
-
try {
|
|
64
|
-
// Fetch all blog posts for public users or admins; filter by userId for non-admin authenticated users
|
|
65
|
-
const url = userId && !isAdmin
|
|
66
|
-
? `${BLOG_API_URL}?pagination[pageSize]=100&fields[0]=title&fields[1]=description&fields[2]=author&fields[3]=publishedAt&fields[4]=id&fields[5]=documentId&filters[authId][$eq]=${userId}`
|
|
67
|
-
: `${BLOG_API_URL}?pagination[pageSize]=100&fields[0]=title&fields[1]=description&fields[2]=author&fields[3]=publishedAt&fields[4]=id&fields[5]=documentId`;
|
|
68
|
-
|
|
69
|
-
const response = await fetch(url, {
|
|
70
|
-
headers: {
|
|
71
|
-
"Content-Type": "application/json",
|
|
72
|
-
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
73
|
-
},
|
|
74
|
-
cache: "no-store",
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
if (!response.ok) {
|
|
78
|
-
const errorText = await response.text();
|
|
79
|
-
throw new Error(`Failed to fetch blog posts: ${errorText}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const result = await response.json();
|
|
83
|
-
const blogPosts = (result.data || []).map((post: any) => ({
|
|
84
|
-
id: post.id || 0,
|
|
85
|
-
documentId: post.documentId || "",
|
|
86
|
-
title: post.attributes?.title || post.title || "",
|
|
87
|
-
description: post.attributes?.description || post.description || "",
|
|
88
|
-
author: post.attributes?.author || post.author || "",
|
|
89
|
-
publishedAt: post.attributes?.publishedAt ? new Date(post.attributes.publishedAt).toISOString() : new Date().toISOString(),
|
|
90
|
-
}));
|
|
91
|
-
|
|
92
|
-
return blogPosts.filter((post: BlogPost) => post.title && post.description);
|
|
93
|
-
} catch (error) {
|
|
94
|
-
console.error("Error fetching blog posts:", error);
|
|
95
|
-
throw error;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export async function GET(request: NextRequest) {
|
|
100
|
-
try {
|
|
101
|
-
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
102
|
-
return NextResponse.json(
|
|
103
|
-
{ error: "Server configuration error: Missing required environment variables" },
|
|
104
|
-
{ status: 500 }
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const { userId } = getAuth(request);
|
|
109
|
-
const user = userId ? await verifyUser(userId) : null;
|
|
110
|
-
const isAdmin = user ? user.businessAdminId === ADMIN_BUSINESS_ID : false;
|
|
111
|
-
|
|
112
|
-
// Allow public access (no userId) or authenticated users to fetch blog posts
|
|
113
|
-
const blogPosts = await getBlogPosts(userId, isAdmin);
|
|
114
|
-
|
|
115
|
-
return NextResponse.json({ data: { blogPosts } });
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error("GET /api/blog: Error:", error);
|
|
118
|
-
return NextResponse.json(
|
|
119
|
-
{ error: error instanceof Error ? error.message : "An error occurred while fetching blog posts" },
|
|
120
|
-
{ status: 500 }
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export async function POST(request: NextRequest) {
|
|
126
|
-
const { userId } = getAuth(request);
|
|
127
|
-
if (!userId) {
|
|
128
|
-
return NextResponse.json({ error: "Unauthorized: No user ID" }, { status: 401 });
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const user = await verifyUser(userId);
|
|
132
|
-
if (!user || user.businessAdminId !== ADMIN_BUSINESS_ID) {
|
|
133
|
-
return NextResponse.json({ error: "Unauthorized: Only admin can create blog posts" }, { status: 403 });
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
138
|
-
return NextResponse.json(
|
|
139
|
-
{ error: "Server configuration error: Missing required environment variables" },
|
|
140
|
-
{ status: 500 }
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const { data } = await request.json();
|
|
145
|
-
if (!data || !data.title || !data.description || !data.author) {
|
|
146
|
-
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const response = await fetch(BLOG_API_URL, {
|
|
150
|
-
method: "POST",
|
|
151
|
-
headers: {
|
|
152
|
-
"Content-Type": "application/json",
|
|
153
|
-
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
154
|
-
},
|
|
155
|
-
body: JSON.stringify({
|
|
156
|
-
data: {
|
|
157
|
-
title: data.title,
|
|
158
|
-
description: data.description,
|
|
159
|
-
author: data.author,
|
|
160
|
-
publishedAt: new Date().toISOString(),
|
|
161
|
-
authId: userId,
|
|
162
|
-
},
|
|
163
|
-
}),
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
if (!response.ok) {
|
|
167
|
-
const errorText = await response.text();
|
|
168
|
-
let errorData = {};
|
|
169
|
-
try {
|
|
170
|
-
errorData = JSON.parse(errorText);
|
|
171
|
-
} catch (parseError) {
|
|
172
|
-
console.error("Failed to parse Strapi response:", parseError);
|
|
173
|
-
}
|
|
174
|
-
return NextResponse.json(
|
|
175
|
-
{ error: `Failed to create blog post: ${response.status} - ${JSON.stringify(errorData)}` },
|
|
176
|
-
{ status: response.status }
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const blogPosts = await getBlogPosts(userId, true);
|
|
181
|
-
return NextResponse.json({ data: { blogPosts } });
|
|
182
|
-
} catch (error) {
|
|
183
|
-
console.error("POST /api/blog: Error:", error);
|
|
184
|
-
return NextResponse.json(
|
|
185
|
-
{ error: error instanceof Error ? error.message : "An error occurred while creating blog post" },
|
|
186
|
-
{ status: 500 }
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// api/blog.ts
|
|
192
|
-
export async function PUT(request: NextRequest) {
|
|
193
|
-
const { userId } = getAuth(request);
|
|
194
|
-
if (!userId) {
|
|
195
|
-
return NextResponse.json({ error: "Unauthorized: No user ID" }, { status: 401 });
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const user = await verifyUser(userId);
|
|
199
|
-
if (!user || user.businessAdminId !== ADMIN_BUSINESS_ID) {
|
|
200
|
-
return NextResponse.json({ error: "Unauthorized: Only admin can update blog posts" }, { status: 403 });
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
205
|
-
return NextResponse.json(
|
|
206
|
-
{ error: "Server configuration error: Missing required environment variables" },
|
|
207
|
-
{ status: 500 }
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const { documentId, data } = await request.json();
|
|
212
|
-
if (!documentId || !data || !data.title || !data.description || !data.author) {
|
|
213
|
-
return NextResponse.json({ error: "Missing required fields or documentId" }, { status: 400 });
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const response = await fetch(`${BLOG_API_URL}/${documentId}`, {
|
|
217
|
-
method: "PUT",
|
|
218
|
-
headers: {
|
|
219
|
-
"Content-Type": "application/json",
|
|
220
|
-
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
221
|
-
},
|
|
222
|
-
body: JSON.stringify({
|
|
223
|
-
data: {
|
|
224
|
-
title: data.title,
|
|
225
|
-
description: data.description,
|
|
226
|
-
author: data.author,
|
|
227
|
-
publishedAt: new Date().toISOString(),
|
|
228
|
-
authId: userId,
|
|
229
|
-
},
|
|
230
|
-
}),
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
if (!response.ok) {
|
|
234
|
-
const errorText = await response.text();
|
|
235
|
-
let errorData = {};
|
|
236
|
-
try {
|
|
237
|
-
errorData = JSON.parse(errorText);
|
|
238
|
-
} catch (parseError) {
|
|
239
|
-
console.error("Failed to parse Strapi response:", parseError);
|
|
240
|
-
}
|
|
241
|
-
return NextResponse.json(
|
|
242
|
-
{ error: `Failed to update blog post: ${response.status} - ${JSON.stringify(errorData)}` },
|
|
243
|
-
{ status: response.status }
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const blogPosts = await getBlogPosts(userId, true);
|
|
248
|
-
return NextResponse.json({ data: { blogPosts } });
|
|
249
|
-
} catch (error) {
|
|
250
|
-
console.error("PUT /api/blog: Error:", error);
|
|
251
|
-
return NextResponse.json(
|
|
252
|
-
{ error: error instanceof Error ? error.message : "An error occurred while updating blog post" },
|
|
253
|
-
{ status: 500 }
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export async function DELETE(request: NextRequest) {
|
|
259
|
-
const { userId } = getAuth(request);
|
|
260
|
-
if (!userId) {
|
|
261
|
-
return NextResponse.json({ error: "Unauthorized: No user ID" }, { status: 401 });
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const user = await verifyUser(userId);
|
|
265
|
-
if (!user || user.businessAdminId !== ADMIN_BUSINESS_ID) {
|
|
266
|
-
return NextResponse.json({ error: "Unauthorized: Only admin can delete blog posts" }, { status: 403 });
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
try {
|
|
270
|
-
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
271
|
-
return NextResponse.json(
|
|
272
|
-
{ error: "Server configuration error: Missing required environment variables" },
|
|
273
|
-
{ status: 500 }
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const { documentId } = await request.json();
|
|
278
|
-
if (!documentId) {
|
|
279
|
-
return NextResponse.json({ error: "Missing documentId" }, { status: 400 });
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const response = await fetch(`${BLOG_API_URL}/${documentId}`, {
|
|
283
|
-
method: "DELETE",
|
|
284
|
-
headers: {
|
|
285
|
-
"Content-Type": "application/json",
|
|
286
|
-
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
if (!response.ok) {
|
|
291
|
-
const errorText = await response.text();
|
|
292
|
-
return NextResponse.json(
|
|
293
|
-
{ error: `Failed to delete blog post: ${errorText}` },
|
|
294
|
-
{ status: response.status }
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const blogPosts = await getBlogPosts(userId, true);
|
|
299
|
-
return NextResponse.json({ data: { blogPosts } });
|
|
300
|
-
} catch (error) {
|
|
301
|
-
console.error("DELETE /api/blog: Error:", error);
|
|
302
|
-
return NextResponse.json(
|
|
303
|
-
{ error: error instanceof Error ? error.message : "An error occurred while deleting blog post" },
|
|
304
|
-
{ status: 500 }
|
|
305
|
-
);
|
|
306
|
-
}
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
+
import { getAuth } from "@clerk/nextjs/server";
|
|
3
|
+
|
|
4
|
+
interface StrapiUser {
|
|
5
|
+
id: number;
|
|
6
|
+
username: string;
|
|
7
|
+
email: string;
|
|
8
|
+
businessAdminId?: string;
|
|
9
|
+
firstName?: string;
|
|
10
|
+
lastName?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface BlogPost {
|
|
14
|
+
id: number;
|
|
15
|
+
documentId: string;
|
|
16
|
+
title: string;
|
|
17
|
+
description: string;
|
|
18
|
+
author: string;
|
|
19
|
+
publishedAt: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const BLOG_API_URL = process.env.STRAPI_BLOG_API_URL || "";
|
|
23
|
+
const STRAPI_USER_LIST_API_URL = process.env.STRAPI_USER_LIST_API_URL || "";
|
|
24
|
+
const ADMIN_BUSINESS_ID = process.env.ADMIN_BUSINESS_ID || "";
|
|
25
|
+
const STRAPI_API_TOKEN = process.env.STRAPI_API_TOKEN || "";
|
|
26
|
+
|
|
27
|
+
async function verifyUser(userId: string): Promise<StrapiUser | null> {
|
|
28
|
+
try {
|
|
29
|
+
const response = await fetch(
|
|
30
|
+
`${STRAPI_USER_LIST_API_URL}?filters[authId][$eq]=${userId}`,
|
|
31
|
+
{
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
console.error("User verification failed:", response.status);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const userData = await response.json();
|
|
45
|
+
const strapiUser = userData.data?.find((user: any) => user.authId === userId);
|
|
46
|
+
if (!strapiUser) return null;
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
id: strapiUser.id,
|
|
50
|
+
username: strapiUser.username,
|
|
51
|
+
email: strapiUser.email,
|
|
52
|
+
businessAdminId: strapiUser.businessAdminId,
|
|
53
|
+
firstName: strapiUser.firstName,
|
|
54
|
+
lastName: strapiUser.lastName,
|
|
55
|
+
};
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("Error verifying user:", error);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function getBlogPosts(userId: string | null, isAdmin: boolean): Promise<BlogPost[]> {
|
|
63
|
+
try {
|
|
64
|
+
// Fetch all blog posts for public users or admins; filter by userId for non-admin authenticated users
|
|
65
|
+
const url = userId && !isAdmin
|
|
66
|
+
? `${BLOG_API_URL}?pagination[pageSize]=100&fields[0]=title&fields[1]=description&fields[2]=author&fields[3]=publishedAt&fields[4]=id&fields[5]=documentId&filters[authId][$eq]=${userId}`
|
|
67
|
+
: `${BLOG_API_URL}?pagination[pageSize]=100&fields[0]=title&fields[1]=description&fields[2]=author&fields[3]=publishedAt&fields[4]=id&fields[5]=documentId`;
|
|
68
|
+
|
|
69
|
+
const response = await fetch(url, {
|
|
70
|
+
headers: {
|
|
71
|
+
"Content-Type": "application/json",
|
|
72
|
+
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
73
|
+
},
|
|
74
|
+
cache: "no-store",
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
const errorText = await response.text();
|
|
79
|
+
throw new Error(`Failed to fetch blog posts: ${errorText}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const result = await response.json();
|
|
83
|
+
const blogPosts = (result.data || []).map((post: any) => ({
|
|
84
|
+
id: post.id || 0,
|
|
85
|
+
documentId: post.documentId || "",
|
|
86
|
+
title: post.attributes?.title || post.title || "",
|
|
87
|
+
description: post.attributes?.description || post.description || "",
|
|
88
|
+
author: post.attributes?.author || post.author || "",
|
|
89
|
+
publishedAt: post.attributes?.publishedAt ? new Date(post.attributes.publishedAt).toISOString() : new Date().toISOString(),
|
|
90
|
+
}));
|
|
91
|
+
|
|
92
|
+
return blogPosts.filter((post: BlogPost) => post.title && post.description);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error("Error fetching blog posts:", error);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export async function GET(request: NextRequest) {
|
|
100
|
+
try {
|
|
101
|
+
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
102
|
+
return NextResponse.json(
|
|
103
|
+
{ error: "Server configuration error: Missing required environment variables" },
|
|
104
|
+
{ status: 500 }
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const { userId } = getAuth(request);
|
|
109
|
+
const user = userId ? await verifyUser(userId) : null;
|
|
110
|
+
const isAdmin = user ? user.businessAdminId === ADMIN_BUSINESS_ID : false;
|
|
111
|
+
|
|
112
|
+
// Allow public access (no userId) or authenticated users to fetch blog posts
|
|
113
|
+
const blogPosts = await getBlogPosts(userId, isAdmin);
|
|
114
|
+
|
|
115
|
+
return NextResponse.json({ data: { blogPosts } });
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error("GET /api/blog: Error:", error);
|
|
118
|
+
return NextResponse.json(
|
|
119
|
+
{ error: error instanceof Error ? error.message : "An error occurred while fetching blog posts" },
|
|
120
|
+
{ status: 500 }
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export async function POST(request: NextRequest) {
|
|
126
|
+
const { userId } = getAuth(request);
|
|
127
|
+
if (!userId) {
|
|
128
|
+
return NextResponse.json({ error: "Unauthorized: No user ID" }, { status: 401 });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const user = await verifyUser(userId);
|
|
132
|
+
if (!user || user.businessAdminId !== ADMIN_BUSINESS_ID) {
|
|
133
|
+
return NextResponse.json({ error: "Unauthorized: Only admin can create blog posts" }, { status: 403 });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
138
|
+
return NextResponse.json(
|
|
139
|
+
{ error: "Server configuration error: Missing required environment variables" },
|
|
140
|
+
{ status: 500 }
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const { data } = await request.json();
|
|
145
|
+
if (!data || !data.title || !data.description || !data.author) {
|
|
146
|
+
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const response = await fetch(BLOG_API_URL, {
|
|
150
|
+
method: "POST",
|
|
151
|
+
headers: {
|
|
152
|
+
"Content-Type": "application/json",
|
|
153
|
+
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
154
|
+
},
|
|
155
|
+
body: JSON.stringify({
|
|
156
|
+
data: {
|
|
157
|
+
title: data.title,
|
|
158
|
+
description: data.description,
|
|
159
|
+
author: data.author,
|
|
160
|
+
publishedAt: new Date().toISOString(),
|
|
161
|
+
authId: userId,
|
|
162
|
+
},
|
|
163
|
+
}),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (!response.ok) {
|
|
167
|
+
const errorText = await response.text();
|
|
168
|
+
let errorData = {};
|
|
169
|
+
try {
|
|
170
|
+
errorData = JSON.parse(errorText);
|
|
171
|
+
} catch (parseError) {
|
|
172
|
+
console.error("Failed to parse Strapi response:", parseError);
|
|
173
|
+
}
|
|
174
|
+
return NextResponse.json(
|
|
175
|
+
{ error: `Failed to create blog post: ${response.status} - ${JSON.stringify(errorData)}` },
|
|
176
|
+
{ status: response.status }
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const blogPosts = await getBlogPosts(userId, true);
|
|
181
|
+
return NextResponse.json({ data: { blogPosts } });
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error("POST /api/blog: Error:", error);
|
|
184
|
+
return NextResponse.json(
|
|
185
|
+
{ error: error instanceof Error ? error.message : "An error occurred while creating blog post" },
|
|
186
|
+
{ status: 500 }
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// api/blog.ts
|
|
192
|
+
export async function PUT(request: NextRequest) {
|
|
193
|
+
const { userId } = getAuth(request);
|
|
194
|
+
if (!userId) {
|
|
195
|
+
return NextResponse.json({ error: "Unauthorized: No user ID" }, { status: 401 });
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const user = await verifyUser(userId);
|
|
199
|
+
if (!user || user.businessAdminId !== ADMIN_BUSINESS_ID) {
|
|
200
|
+
return NextResponse.json({ error: "Unauthorized: Only admin can update blog posts" }, { status: 403 });
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
205
|
+
return NextResponse.json(
|
|
206
|
+
{ error: "Server configuration error: Missing required environment variables" },
|
|
207
|
+
{ status: 500 }
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const { documentId, data } = await request.json();
|
|
212
|
+
if (!documentId || !data || !data.title || !data.description || !data.author) {
|
|
213
|
+
return NextResponse.json({ error: "Missing required fields or documentId" }, { status: 400 });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const response = await fetch(`${BLOG_API_URL}/${documentId}`, {
|
|
217
|
+
method: "PUT",
|
|
218
|
+
headers: {
|
|
219
|
+
"Content-Type": "application/json",
|
|
220
|
+
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
221
|
+
},
|
|
222
|
+
body: JSON.stringify({
|
|
223
|
+
data: {
|
|
224
|
+
title: data.title,
|
|
225
|
+
description: data.description,
|
|
226
|
+
author: data.author,
|
|
227
|
+
publishedAt: new Date().toISOString(),
|
|
228
|
+
authId: userId,
|
|
229
|
+
},
|
|
230
|
+
}),
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
if (!response.ok) {
|
|
234
|
+
const errorText = await response.text();
|
|
235
|
+
let errorData = {};
|
|
236
|
+
try {
|
|
237
|
+
errorData = JSON.parse(errorText);
|
|
238
|
+
} catch (parseError) {
|
|
239
|
+
console.error("Failed to parse Strapi response:", parseError);
|
|
240
|
+
}
|
|
241
|
+
return NextResponse.json(
|
|
242
|
+
{ error: `Failed to update blog post: ${response.status} - ${JSON.stringify(errorData)}` },
|
|
243
|
+
{ status: response.status }
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const blogPosts = await getBlogPosts(userId, true);
|
|
248
|
+
return NextResponse.json({ data: { blogPosts } });
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error("PUT /api/blog: Error:", error);
|
|
251
|
+
return NextResponse.json(
|
|
252
|
+
{ error: error instanceof Error ? error.message : "An error occurred while updating blog post" },
|
|
253
|
+
{ status: 500 }
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export async function DELETE(request: NextRequest) {
|
|
259
|
+
const { userId } = getAuth(request);
|
|
260
|
+
if (!userId) {
|
|
261
|
+
return NextResponse.json({ error: "Unauthorized: No user ID" }, { status: 401 });
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const user = await verifyUser(userId);
|
|
265
|
+
if (!user || user.businessAdminId !== ADMIN_BUSINESS_ID) {
|
|
266
|
+
return NextResponse.json({ error: "Unauthorized: Only admin can delete blog posts" }, { status: 403 });
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
if (!BLOG_API_URL || !STRAPI_API_TOKEN) {
|
|
271
|
+
return NextResponse.json(
|
|
272
|
+
{ error: "Server configuration error: Missing required environment variables" },
|
|
273
|
+
{ status: 500 }
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const { documentId } = await request.json();
|
|
278
|
+
if (!documentId) {
|
|
279
|
+
return NextResponse.json({ error: "Missing documentId" }, { status: 400 });
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const response = await fetch(`${BLOG_API_URL}/${documentId}`, {
|
|
283
|
+
method: "DELETE",
|
|
284
|
+
headers: {
|
|
285
|
+
"Content-Type": "application/json",
|
|
286
|
+
Authorization: `Bearer ${STRAPI_API_TOKEN}`,
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
if (!response.ok) {
|
|
291
|
+
const errorText = await response.text();
|
|
292
|
+
return NextResponse.json(
|
|
293
|
+
{ error: `Failed to delete blog post: ${errorText}` },
|
|
294
|
+
{ status: response.status }
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const blogPosts = await getBlogPosts(userId, true);
|
|
299
|
+
return NextResponse.json({ data: { blogPosts } });
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error("DELETE /api/blog: Error:", error);
|
|
302
|
+
return NextResponse.json(
|
|
303
|
+
{ error: error instanceof Error ? error.message : "An error occurred while deleting blog post" },
|
|
304
|
+
{ status: 500 }
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
307
|
}
|
package/app/api/chat/route.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { openai } from "@ai-sdk/openai";
|
|
2
|
-
import { streamText } from "ai";
|
|
3
|
-
|
|
4
|
-
export const maxDuration = 30;
|
|
5
|
-
|
|
6
|
-
export async function POST(req: Request) {
|
|
7
|
-
const { messages } = await req.json();
|
|
8
|
-
|
|
9
|
-
const result = await streamText({
|
|
10
|
-
model: openai("gpt-3.5-turbo"),
|
|
11
|
-
messages,
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
return result.toDataStreamResponse();
|
|
1
|
+
import { openai } from "@ai-sdk/openai";
|
|
2
|
+
import { streamText } from "ai";
|
|
3
|
+
|
|
4
|
+
export const maxDuration = 30;
|
|
5
|
+
|
|
6
|
+
export async function POST(req: Request) {
|
|
7
|
+
const { messages } = await req.json();
|
|
8
|
+
|
|
9
|
+
const result = await streamText({
|
|
10
|
+
model: openai("gpt-3.5-turbo"),
|
|
11
|
+
messages,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return result.toDataStreamResponse();
|
|
15
15
|
}
|