langueages

This commit is contained in:
2026-06-29 20:29:41 +03:00
parent 958152a688
commit e30cbfa132
19 changed files with 1014 additions and 40 deletions
@@ -1,10 +1,12 @@
"use client";
import { useEffect, useState, useRef } from "react";
import React, { useEffect, useState, useRef, Fragment } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { MenuCategory, MenuItem as MenuItemType } from "@/data/menu";
import { CategoryNav } from "@/components/CategoryNav";
import { MenuItem } from "@/components/MenuItem";
import { useTranslations, useLocale } from "next-intl";
import { useRouter, usePathname } from "@/i18n/routing";
export const CATEGORY_ICONS: Record<string, string> = {
"kahvaltiliklar": "🌅",
@@ -41,6 +43,10 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
);
const [selectedItem, setSelectedItem] = useState<MenuItemType | null>(null);
const sectionRefs = useRef<(HTMLElement | null)[]>([]);
const t = useTranslations("Menu");
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
useEffect(() => {
const observer = new IntersectionObserver(
@@ -120,8 +126,28 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
className="text-xs font-sans tracking-wide"
style={{ color: "rgba(255,218,168,0.5)" }}
>
Akyaka&apos;nın en keyifli menüsü
{t('subtitle')}
</p>
<div className="mt-8 flex items-center gap-4">
{['tr', 'en', 'ru', 'de'].map((l, index) => (
<React.Fragment key={l}>
<button
onClick={() => router.replace(pathname, { locale: l })}
className={`text-[11px] font-sans tracking-[0.25em] uppercase transition-all duration-300 ${
locale === l
? 'text-white opacity-100 scale-105'
: 'text-white/40 hover:text-white/70 hover:scale-100'
}`}
>
{l}
</button>
{index < 3 && (
<div className="w-px h-3" style={{ background: "rgba(255,190,100,0.2)" }} />
)}
</React.Fragment>
))}
</div>
</motion.div>
</div>
@@ -170,7 +196,7 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
{CATEGORY_ICONS[category.id] ?? "🍽️"}
</span>
<h2
className="font-display text-[22px] leading-tight font-semibold italic"
className="font-display text-[22px] leading-tight font-semibold italic uppercase tracking-wider"
style={{ color: "var(--stone-ink)" }}
>
{category.title}
@@ -217,8 +243,17 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
className="text-[11px] font-sans"
style={{ color: "rgba(120,90,60,0.5)" }}
>
© 2026 Moy Beach. Tüm hakları saklıdır.
© 2026 {siteSettings.restaurantName}. {t('allRightsReserved')}
</p>
<a
href="https://ayris.tech"
target="_blank"
rel="noopener noreferrer"
className="mt-6 text-[10px] font-sans tracking-[0.2em] uppercase transition-colors hover:text-white/80"
style={{ color: "rgba(160,100,50,0.4)" }}
>
Created by <span className="font-semibold">ayris.tech</span>
</a>
</div>
</footer>
@@ -240,7 +275,7 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
onClick={(e) => e.stopPropagation()}
>
{selectedItem.image && (
<div className="w-full h-56 relative">
<div className="w-full h-80 relative">
<img src={selectedItem.image} alt={selectedItem.name} className="w-full h-full object-cover" />
<button
className="absolute top-3 right-3 bg-black/50 text-white w-8 h-8 rounded-full flex items-center justify-center backdrop-blur-md transition-colors hover:bg-black/70"
+58
View File
@@ -0,0 +1,58 @@
import type { Metadata } from "next";
import { Cormorant_Garamond, Plus_Jakarta_Sans } from "next/font/google";
import {NextIntlClientProvider} from 'next-intl';
import {getMessages, setRequestLocale} from 'next-intl/server';
import {routing} from '@/i18n/routing';
import {notFound} from 'next/navigation';
import "../globals.css";
const cormorant = Cormorant_Garamond({
variable: "--font-cormorant",
subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
style: ["normal", "italic"],
display: "swap",
});
const jakarta = Plus_Jakarta_Sans({
variable: "--font-jakarta",
subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
display: "swap",
});
export const metadata: Metadata = {
title: "Moy Beach Akyaka | Menü",
description: "Moy Beach Akyaka dijital menü.",
};
export function generateStaticParams() {
return routing.locales.map((locale) => ({locale}));
}
export default async function LocaleLayout({
children,
params
}: {
children: React.ReactNode;
params: Promise<{locale: string}>;
}) {
const {locale} = await params;
if (!routing.locales.includes(locale as any)) {
notFound();
}
setRequestLocale(locale);
const messages = await getMessages();
return (
<html lang={locale} className={`${cormorant.variable} ${jakarta.variable} h-full`}>
<body className="min-h-full flex flex-col antialiased" suppressHydrationWarning>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
+16 -6
View File
@@ -1,8 +1,10 @@
import prisma from "@/lib/prisma";
import MenuClient from "./MenuClient";
import { MenuCategory } from "@/data/menu";
import { setRequestLocale } from 'next-intl/server';
import { routing } from '@/i18n/routing';
async function getMenuData(): Promise<MenuCategory[]> {
async function getMenuData(locale: string): Promise<MenuCategory[]> {
const dbCategories = await prisma.categories.findMany({
where: { status: 1 },
orderBy: { order_num: "asc" },
@@ -17,11 +19,11 @@ async function getMenuData(): Promise<MenuCategory[]> {
const categoryProducts = dbProducts.filter((p) => p.category_id === cat.id);
return {
id: cat.slug,
title: cat.name_tr,
title: (cat.name_i18n as Record<string, string>)?.[locale] || (locale === 'tr' ? cat.name_tr : cat.name),
items: categoryProducts.map((p) => ({
id: p.id.toString(),
name: p.name_tr,
description: p.description_tr,
name: (p.name_i18n as Record<string, string>)?.[locale] || (locale === 'tr' ? p.name_tr : p.name),
description: (p.description_i18n as Record<string, string>)?.[locale] || (locale === 'tr' ? p.description_tr : (p.description || '')),
price: p.price.toString() + " ₺",
image: p.image_url || '/default-product.png',
})),
@@ -43,11 +45,19 @@ async function getSiteSettings() {
}
}
export default async function Page() {
export default async function Page({
params
}: {
params: Promise<{ locale: string }>
}) {
const { locale } = await params;
setRequestLocale(locale);
const [menuData, siteSettings] = await Promise.all([
getMenuData(),
getMenuData(locale),
getSiteSettings(),
]);
return <MenuClient initialCategories={menuData} siteSettings={siteSettings} />;
}
@@ -19,6 +19,7 @@ export async function createCategory(_prevState: unknown, formData: FormData) {
data: {
name,
name_tr,
name_i18n: { en: name, tr: name_tr, ru: '', de: '' },
slug: name_tr.toLowerCase().replace(/[^a-z0-9]+/g, '-'),
order_num,
status,
@@ -50,6 +51,7 @@ export async function updateCategory(id: number, _prevState: unknown, formData:
data: {
name,
name_tr,
name_i18n: { en: name, tr: name_tr, ru: '', de: '' },
slug: name_tr.toLowerCase().replace(/[^a-z0-9]+/g, '-'),
order_num,
status,
@@ -22,10 +22,12 @@ export async function createProduct(_prevState: unknown, formData: FormData) {
data: {
name,
name_tr,
name_i18n: { en: name, tr: name_tr, ru: '', de: '' },
slug: name_tr.toLowerCase().replace(/[^a-z0-9]+/g, '-'),
price,
category_id,
description_tr,
description_i18n: { en: '', tr: description_tr, ru: '', de: '' },
image_url,
status,
}
@@ -59,10 +61,12 @@ export async function updateProduct(id: number, _prevState: unknown, formData: F
data: {
name,
name_tr,
name_i18n: { en: name, tr: name_tr, ru: '', de: '' },
slug: name_tr.toLowerCase().replace(/[^a-z0-9]+/g, '-'),
price,
category_id,
description_tr,
description_i18n: { en: '', tr: description_tr, ru: '', de: '' },
image_url,
status,
}
+1 -1
View File
@@ -1,6 +1,6 @@
import type { Metadata } from "next";
import { Cormorant_Garamond, Plus_Jakarta_Sans } from "next/font/google";
import "./globals.css";
import "../globals.css";
const cormorant = Cormorant_Garamond({
variable: "--font-cormorant",
+1 -1
View File
@@ -50,7 +50,7 @@ export function CategoryNav({ categories, activeCategoryId, icons }: CategoryNav
onClick={() => scrollTo(cat.id)}
className={`
flex items-center gap-1.5 whitespace-nowrap px-3 py-1.5 rounded-full
text-[11px] font-medium font-sans shrink-0
text-[11px] font-semibold font-sans shrink-0 uppercase tracking-widest
transition-all duration-200 active:scale-95
${active ? "pill-active" : "pill-inactive hover:bg-[rgba(120,90,58,0.14)]"}
`}
+17
View File
@@ -0,0 +1,17 @@
import {getRequestConfig} from 'next-intl/server';
import {routing} from './routing';
export default getRequestConfig(async ({requestLocale}) => {
// This typically corresponds to the `[locale]` segment
let locale = await requestLocale;
// Ensure that a valid locale is used
if (!locale || !routing.locales.includes(locale as any)) {
locale = routing.defaultLocale;
}
return {
locale,
messages: (await import(`../messages/${locale}.json`)).default
};
});
+11
View File
@@ -0,0 +1,11 @@
import {defineRouting} from 'next-intl/routing';
import {createNavigation} from 'next-intl/navigation';
export const routing = defineRouting({
locales: ['tr', 'en', 'ru', 'de'],
defaultLocale: 'en',
localePrefix: 'always'
});
export const {Link, redirect, usePathname, useRouter, getPathname} =
createNavigation(routing);
+6
View File
@@ -0,0 +1,6 @@
{
"Menu": {
"subtitle": "Akyakas köstlichstes Menü",
"allRightsReserved": "Alle Rechte vorbehalten."
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"Menu": {
"subtitle": "Akyaka's most delightful menu",
"allRightsReserved": "All rights reserved."
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"Menu": {
"subtitle": "Самое восхитительное меню Акяки",
"allRightsReserved": "Все права защищены."
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"Menu": {
"subtitle": "Akyaka'nın en keyifli menüsü",
"allRightsReserved": "Tüm hakları saklıdır."
}
}
+4 -1
View File
@@ -1,4 +1,7 @@
import type { NextConfig } from "next";
import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin('./i18n/request.ts');
const nextConfig: NextConfig = {
output: "standalone",
@@ -17,4 +20,4 @@ const nextConfig: NextConfig = {
/* other config options here */
};
export default nextConfig;
export default withNextIntl(nextConfig);
+731 -3
View File
@@ -17,6 +17,7 @@
"lucide-react": "^1.17.0",
"next": "16.2.7",
"next-cloudinary": "^6.17.5",
"next-intl": "^4.13.0",
"pg": "^8.21.0",
"react": "19.2.4",
"react-dom": "19.2.4"
@@ -552,6 +553,36 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@formatjs/fast-memoize": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.6.tgz",
"integrity": "sha512-H5aexk1Le7T9TPmscacZ+1pR6CTa2n1wq+HDVGXhH8TzUlQQpeXzZs91dRtmFHrbeNbjPFPfQujUqm7MHgVoXQ==",
"license": "MIT"
},
"node_modules/@formatjs/icu-messageformat-parser": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.12.tgz",
"integrity": "sha512-YyzzxVgYJ8DELmmkhn0Yr0rUj0dTJFf9Jp628K3S0ysInBWxLVDOS8i3RP91cCp4DMK4WYb4cVMhWA9i4knSJg==",
"license": "MIT",
"dependencies": {
"@formatjs/icu-skeleton-parser": "2.1.10"
}
},
"node_modules/@formatjs/icu-skeleton-parser": {
"version": "2.1.10",
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.10.tgz",
"integrity": "sha512-XuSva+8ZGawk8VnD5VD6UeH8KarQ/Z022zgjHDoHmlNiAewstXuuzXc0Hk5pGFSdG+nNw5bfJKXqj1ZXHn9yUA==",
"license": "MIT"
},
"node_modules/@formatjs/intl-localematcher": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.8.10.tgz",
"integrity": "sha512-P/IC3qws3jH+1fEs+o0RIFgXKRaQlFehjS5W0FPAqdo6hgzawLl+eD0q0JjheQ3XtoOe5n8WSYfX06KQZI/QJA==",
"license": "MIT",
"dependencies": {
"@formatjs/fast-memoize": "3.1.6"
}
},
"node_modules/@hono/node-server": {
"version": "1.19.11",
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz",
@@ -1425,6 +1456,331 @@
"node": ">=12.4.0"
}
},
"node_modules/@parcel/watcher": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
"integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"detect-libc": "^2.0.3",
"is-glob": "^4.0.3",
"node-addon-api": "^7.0.0",
"picomatch": "^4.0.3"
},
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"@parcel/watcher-android-arm64": "2.5.6",
"@parcel/watcher-darwin-arm64": "2.5.6",
"@parcel/watcher-darwin-x64": "2.5.6",
"@parcel/watcher-freebsd-x64": "2.5.6",
"@parcel/watcher-linux-arm-glibc": "2.5.6",
"@parcel/watcher-linux-arm-musl": "2.5.6",
"@parcel/watcher-linux-arm64-glibc": "2.5.6",
"@parcel/watcher-linux-arm64-musl": "2.5.6",
"@parcel/watcher-linux-x64-glibc": "2.5.6",
"@parcel/watcher-linux-x64-musl": "2.5.6",
"@parcel/watcher-win32-arm64": "2.5.6",
"@parcel/watcher-win32-ia32": "2.5.6",
"@parcel/watcher-win32-x64": "2.5.6"
}
},
"node_modules/@parcel/watcher-android-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
"integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
"integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-x64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
"integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-freebsd-x64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
"integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-glibc": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
"integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
"cpu": [
"arm"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-musl": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
"integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
"cpu": [
"arm"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-glibc": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
"integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-musl": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
"integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-glibc": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
"integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-musl": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
"integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
"integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-ia32": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
"integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
"cpu": [
"ia32"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-x64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
"integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher/node_modules/picomatch": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@prisma/adapter-pg": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.8.0.tgz",
@@ -1822,6 +2178,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/@schummar/icu-type-parser": {
"version": "1.21.5",
"resolved": "https://registry.npmjs.org/@schummar/icu-type-parser/-/icu-type-parser-1.21.5.tgz",
"integrity": "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==",
"license": "MIT"
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
@@ -1829,6 +2191,222 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/@swc/core-darwin-arm64": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.43.tgz",
"integrity": "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-darwin-x64": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.43.tgz",
"integrity": "sha512-lp3d4Lamc8dt5huYdGLSR+9hLxmfr1jb0l+4XXG2zPqZwYWRN9R0U2qYoTrggiU2RWW0oV9VbWM3kBnqIc2kdQ==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.43.tgz",
"integrity": "sha512-JWTQQELtsG5GgphDrr/XqqmM2pDN3cZqbMS0Mrg+iTiXL3F74sn/S2IyYE/5u4h2KLkTf9qQ7dXyxsbx7YzkeA==",
"cpu": [
"arm"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.43.tgz",
"integrity": "sha512-B4otJRdPWIsmiSBf0uG7Z/+vMWmkufjz5MmYxubwKuZazDW14Zd3symga1N62QR4RT+kEFeHEgsXfZGyn/w0hw==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm64-musl": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.43.tgz",
"integrity": "sha512-6zB6OnpViBxYy4tgY3v2i6AZY9fwkcHZ032UOwtwUuW1d19sdT07qF0kZe6/3UR1tUaK6jjg2rmVcUIBCEYVjQ==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-ppc64-gnu": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.43.tgz",
"integrity": "sha512-coxE1ZWdB3uSDVNoEtYNrRi/1epvckZx9cTJ8ICUxTMTxGk+yvQ/Twacp3ruZSaMPGCriUjP86C37VhaT6nyRg==",
"cpu": [
"ppc64"
],
"libc": [
"glibc"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-s390x-gnu": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.43.tgz",
"integrity": "sha512-lXfLhs+LpBsD5inuYx+YDH5WsPPBQ95KPUiy8P5wq9ob9xKDZFqwNfU2QW6bGO8NqRO/H9JQomTSt5Yyh+FGfA==",
"cpu": [
"s390x"
],
"libc": [
"glibc"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-x64-gnu": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.43.tgz",
"integrity": "sha512-07XnKwTmKy8TGOZG3D9fRnLWGynxPjwQnZLVmBFbo6F+7vHYzBIOuwXEhemrChBWb6yDNZsVCcMWCPX6FDD2xg==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-x64-musl": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.43.tgz",
"integrity": "sha512-TJc+bsSIaBh+hZvZ5GRtW/K1bw66TJ9vsUwvVIsZdiWxU5ObLwZvfcnZ3UpgVfMnFibRes9uriJrQNBHEEogRQ==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.43.tgz",
"integrity": "sha512-jfd7s2/bUQYkOHLs+LWQNKZdmDa8+sufKLllhpWAhVQ2GDCwsHe3vR/j+OSiItZNtkzFuaawa3+SAKz9y5gYfw==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.43.tgz",
"integrity": "sha512-rLAE8JvucqEW1ZGohxPQrQWPBQeJG4+ypKbWfdlU/qmKScvCkxf9/Jxnzki1dkUQCQ7P5Enp13RlvqOlvx/32g==",
"cpu": [
"ia32"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-x64-msvc": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.43.tgz",
"integrity": "sha512-h8MLDHZcfIukwQWj03rIJZx1I0E81AYj2X7J/nGErG4nz+QAv6G1Z+peotvinL3lqpbo32tLYSMFo32/ySzxKg==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/counter": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
"license": "Apache-2.0"
},
"node_modules/@swc/helpers": {
"version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@@ -1838,6 +2416,15 @@
"tslib": "^2.8.0"
}
},
"node_modules/@swc/types": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.27.tgz",
"integrity": "sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==",
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3"
}
},
"node_modules/@tailwindcss/node": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz",
@@ -3623,7 +4210,6 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"devOptional": true,
"license": "Apache-2.0",
"engines": {
"node": ">=8"
@@ -4950,6 +5536,21 @@
"url": "https://opencollective.com/express"
}
},
"node_modules/icu-minify": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/icu-minify/-/icu-minify-4.13.0.tgz",
"integrity": "sha512-SIFMeUHZJjzS5RvIGvybKvWoHjDm9cGVEs2EpJ8PmywOdJLWyblPm7TdPLLoUtkJtwQD7iGhl2WMptZ+N0on+w==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"license": "MIT",
"dependencies": {
"@formatjs/icu-messageformat-parser": "^3.4.0"
}
},
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -5002,6 +5603,16 @@
"node": ">= 0.4"
}
},
"node_modules/intl-messageformat": {
"version": "11.2.9",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.2.9.tgz",
"integrity": "sha512-cGzymZerpDhVXRKjKLgXKda9gI29TU2o88L7gwNMHp3WZVxA/0c5tX52udXbW9JklDApolvMXZG6Dhhdz5eirA==",
"license": "BSD-3-Clause",
"dependencies": {
"@formatjs/fast-memoize": "3.1.6",
"@formatjs/icu-messageformat-parser": "3.5.12"
}
},
"node_modules/is-array-buffer": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
@@ -5164,7 +5775,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -5210,7 +5820,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -6133,6 +6742,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/negotiator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/next": {
"version": "16.2.7",
"resolved": "https://registry.npmjs.org/next/-/next-16.2.7.tgz",
@@ -6201,6 +6819,83 @@
"react": "^17 || ^18 || >=19.0.0-beta || ^19"
}
},
"node_modules/next-intl": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.13.0.tgz",
"integrity": "sha512-OvNq2v5XLx4EkQOsAhVE9g+6zdb83XHusADCXXtIW4LILYnjEVaeINdr1lkVWKSjzwNUiMSlH5N4K0OQTRiv6A==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"license": "MIT",
"dependencies": {
"@formatjs/intl-localematcher": "^0.8.1",
"@parcel/watcher": "^2.4.1",
"@swc/core": "^1.15.2",
"icu-minify": "^4.13.0",
"negotiator": "^1.0.0",
"next-intl-swc-plugin-extractor": "^4.13.0",
"po-parser": "^2.1.1",
"use-intl": "^4.13.0"
},
"peerDependencies": {
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/next-intl-swc-plugin-extractor": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.13.0.tgz",
"integrity": "sha512-6S/fJI0KXvLCL8nhBo9P8eGaJPzmwJBTCzX0NaUIj0VyU8U89d//T+vjMLdNIXl5MlLaYH7B9MbAjb8Mvu+tqQ==",
"license": "MIT"
},
"node_modules/next-intl/node_modules/@swc/core": {
"version": "1.15.43",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.43.tgz",
"integrity": "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3",
"@swc/types": "^0.1.27"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
"@swc/core-darwin-arm64": "1.15.43",
"@swc/core-darwin-x64": "1.15.43",
"@swc/core-linux-arm-gnueabihf": "1.15.43",
"@swc/core-linux-arm64-gnu": "1.15.43",
"@swc/core-linux-arm64-musl": "1.15.43",
"@swc/core-linux-ppc64-gnu": "1.15.43",
"@swc/core-linux-s390x-gnu": "1.15.43",
"@swc/core-linux-x64-gnu": "1.15.43",
"@swc/core-linux-x64-musl": "1.15.43",
"@swc/core-win32-arm64-msvc": "1.15.43",
"@swc/core-win32-ia32-msvc": "1.15.43",
"@swc/core-win32-x64-msvc": "1.15.43"
},
"peerDependencies": {
"@swc/helpers": ">=0.5.17"
},
"peerDependenciesMeta": {
"@swc/helpers": {
"optional": true
}
}
},
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -6229,6 +6924,12 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"license": "MIT"
},
"node_modules/node-exports-info": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz",
@@ -6630,6 +7331,12 @@
"pathe": "^2.0.3"
}
},
"node_modules/po-parser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/po-parser/-/po-parser-2.1.1.tgz",
"integrity": "sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==",
"license": "MIT"
},
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
@@ -7955,6 +8662,27 @@
"punycode": "^2.1.0"
}
},
"node_modules/use-intl": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.13.0.tgz",
"integrity": "sha512-fAFDrWaASxlhXOipcOyb5VDD+YONqj6+8O8EcG/J7RBoOUF3A8YahRWLN+mBxYMrlMQB8N6Voqk5X+YC+HSL0A==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"license": "MIT",
"dependencies": {
"@formatjs/fast-memoize": "^3.1.0",
"@schummar/icu-type-parser": "1.21.5",
"icu-minify": "^4.13.0",
"intl-messageformat": "^11.1.0"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
}
},
"node_modules/valibot": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.2.0.tgz",
+1
View File
@@ -18,6 +18,7 @@
"lucide-react": "^1.17.0",
"next": "16.2.7",
"next-cloudinary": "^6.17.5",
"next-intl": "^4.13.0",
"pg": "^8.21.0",
"react": "19.2.4",
"react-dom": "19.2.4"
+3
View File
@@ -13,6 +13,7 @@ model categories {
id Int @id @default(autoincrement())
name String @db.VarChar(100)
name_tr String @db.Text
name_i18n Json? @default("{}")
slug String @db.VarChar(100)
order_num Int? @default(0)
status Int? @default(1) @db.SmallInt
@@ -30,6 +31,8 @@ model products {
short_description String? @db.VarChar(255)
description String? @db.Text
description_tr String @db.Text
name_i18n Json? @default("{}")
description_i18n Json? @default("{}")
price Decimal @db.Decimal(10, 2)
image_url String? @db.VarChar(255)
status Int? @default(1) @db.SmallInt
+41 -23
View File
@@ -1,38 +1,56 @@
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { updateSession, decrypt } from './lib/auth'
import createIntlMiddleware from 'next-intl/middleware';
import {routing} from './i18n/routing';
export async function proxy(request: NextRequest) {
// Always update session expiration
let response = await updateSession(request)
const handleI18nRouting = createIntlMiddleware(routing);
const isAuthPage = request.nextUrl.pathname.startsWith('/admin/login')
const isAdminPage = request.nextUrl.pathname.startsWith('/admin')
export default async function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
// Check if session exists and is valid
const sessionValue = request.cookies.get('session')?.value
let session = null
if (sessionValue) {
try {
session = await decrypt(sessionValue)
} catch(e) {
session = null
// 1) Handle Admin Routes (Authentication)
if (pathname.startsWith('/admin')) {
let response = await updateSession(request)
const isAuthPage = pathname.startsWith('/admin/login')
const isAdminPage = pathname.startsWith('/admin')
const sessionValue = request.cookies.get('session')?.value
let session = null
if (sessionValue) {
try {
session = await decrypt(sessionValue)
} catch(e) {
session = null
}
}
if (isAdminPage && !isAuthPage && !session) {
return NextResponse.redirect(new URL('/admin/login', request.url))
}
if (isAuthPage && session) {
return NextResponse.redirect(new URL('/admin', request.url))
}
return response || NextResponse.next()
}
// If trying to access admin pages (except login) without a valid session
if (isAdminPage && !isAuthPage && !session) {
return NextResponse.redirect(new URL('/admin/login', request.url))
// 2) Skip API and Static Files
const isInternalOrApi = pathname.startsWith('/api') ||
pathname.startsWith('/_next') ||
pathname.startsWith('/_vercel') ||
pathname.includes('.');
if (isInternalOrApi) {
return NextResponse.next();
}
// If trying to access login page with a valid session
if (isAuthPage && session) {
return NextResponse.redirect(new URL('/admin', request.url))
}
return response || NextResponse.next()
// 3) Handle i18n Routing for the public menu
return handleI18nRouting(request);
}
export const config = {
matcher: ['/admin/:path*'],
// Match everything except internal and api routes
matcher: ['/((?!api|_next|_vercel|.*\\..*).*)'],
}
+60
View File
@@ -0,0 +1,60 @@
import prisma from '../lib/prisma';
async function main() {
console.log('Migration started...');
// 1. Kategorileri Güncelle
const categories = await prisma.categories.findMany();
console.log(`Found ${categories.length} categories.`);
for (const cat of categories) {
const name_i18n = {
en: cat.name,
tr: cat.name_tr
};
await prisma.categories.update({
where: { id: cat.id },
data: {
name_i18n: name_i18n
}
});
}
console.log('Categories migrated.');
// 2. Ürünleri Güncelle
const products = await prisma.products.findMany();
console.log(`Found ${products.length} products.`);
for (const prod of products) {
const name_i18n = {
en: prod.name,
tr: prod.name_tr
};
const description_i18n = {
en: prod.description || '',
tr: prod.description_tr || ''
};
await prisma.products.update({
where: { id: prod.id },
data: {
name_i18n: name_i18n,
description_i18n: description_i18n
}
});
}
console.log('Products migrated.');
console.log('Migration completed successfully!');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});