From 54113726f47bd6a349153f98a9909b7bfa40ba26 Mon Sep 17 00:00:00 2001 From: Kenan KARAER Date: Thu, 29 Jan 2026 16:49:51 +0300 Subject: [PATCH] =?UTF-8?q?g=C3=BCncelleme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PLANLAMA.md | 10 +- app/(dashboard)/dashboard/products/actions.ts | 51 ++- app/(dashboard)/layout.tsx | 3 + app/(public)/login/page.tsx | 3 +- app/(public)/products/page.tsx | 115 +++--- app/(public)/verify-2fa/page.tsx | 130 +++++++ app/layout.tsx | 7 +- build_log.txt | Bin 0 -> 1966 bytes build_log_2.txt | Bin 0 -> 1540 bytes components/dashboard/auto-logout-handler.tsx | 60 +++ components/dashboard/product-form.tsx | 225 ++++++++++-- drop_site_settings.sql | 2 - lib/sms/verification-actions.ts | 124 +++++++ lint_output.txt | Bin 0 -> 2674 bytes lint_output_2.txt | Bin 0 -> 2284 bytes lint_output_3.txt | Bin 0 -> 1834 bytes make_admin.sql | 8 - middleware.ts | 14 +- migrations/schema_full.sql | 345 +++++++++++++++++ next.config.mjs | 4 + nixpacks.toml | 8 + package-lock.json | 346 ++++++++++++++++++ package.json | 9 +- scripts/deploy-migration.ts | 49 +++ scripts/run-migration.js | 39 ++ scripts/run-migration.ts | 42 +++ security_updates.sql | 94 ----- supabase_migration_add_phone.sql | 3 - supabase_migration_tiktok.sql | 9 - supabase_migration_youtube.sql | 9 - supabase_schema.sql | 49 --- supabase_schema_additions.sql | 58 --- supabase_schema_categories.sql | 44 --- supabase_schema_customers.sql | 35 -- supabase_schema_netgsm.sql | 83 ----- supabase_schema_products_category_fk.sql | 6 - supabase_schema_site_contents.sql | 39 -- supabase_schema_sliders.sql | 88 ----- 38 files changed, 1469 insertions(+), 642 deletions(-) create mode 100644 app/(public)/verify-2fa/page.tsx create mode 100644 build_log.txt create mode 100644 build_log_2.txt create mode 100644 components/dashboard/auto-logout-handler.tsx delete mode 100644 drop_site_settings.sql create mode 100644 lib/sms/verification-actions.ts create mode 100644 lint_output.txt create mode 100644 lint_output_2.txt create mode 100644 lint_output_3.txt delete mode 100644 make_admin.sql create mode 100644 migrations/schema_full.sql create mode 100644 nixpacks.toml create mode 100644 scripts/deploy-migration.ts create mode 100644 scripts/run-migration.js create mode 100644 scripts/run-migration.ts delete mode 100644 security_updates.sql delete mode 100644 supabase_migration_add_phone.sql delete mode 100644 supabase_migration_tiktok.sql delete mode 100644 supabase_migration_youtube.sql delete mode 100644 supabase_schema.sql delete mode 100644 supabase_schema_additions.sql delete mode 100644 supabase_schema_categories.sql delete mode 100644 supabase_schema_customers.sql delete mode 100644 supabase_schema_netgsm.sql delete mode 100644 supabase_schema_products_category_fk.sql delete mode 100644 supabase_schema_site_contents.sql delete mode 100644 supabase_schema_sliders.sql diff --git a/PLANLAMA.md b/PLANLAMA.md index 933128c..c2af977 100644 --- a/PLANLAMA.md +++ b/PLANLAMA.md @@ -22,7 +22,11 @@ - [x] Ürün Yönetimi (Temel CRUD). - [x] Kategori Yönetimi (Arayüz hazır, veritabanı bekleniyor). - -## 3. NetGSm Entegrasyonu -- Login için Sms doğrulama entegrasyonu yapılacak. +## 3. Tamamlanan Ek Özellikler (28.01.2026) +- [x] **NetGSM Entegrasyonu:** Login için SMS doğrulama (2FA) eklendi. +- [x] **Oto-Çıkış:** 15dk hareketsizlikte otomatik çıkış. +- [x] **Ürün Geliştirmeleri:** + - Aktif/Pasif durumu. + - Çoklu resim yükleme. + - Resim optimizasyonu. - \ No newline at end of file diff --git a/app/(dashboard)/dashboard/products/actions.ts b/app/(dashboard)/dashboard/products/actions.ts index abee491..d04c349 100644 --- a/app/(dashboard)/dashboard/products/actions.ts +++ b/app/(dashboard)/dashboard/products/actions.ts @@ -9,26 +9,41 @@ interface ProductData { description?: string price: number image_url?: string + is_active?: boolean + images?: string[] } export async function createProduct(data: ProductData) { const supabase = createClient() - // Validate data manually or use Zod schema here again securely - // For simplicity, we assume data is coming from the strongly typed Client Form - // In production, ALWAYS validate server-side strictly. - try { - const { error } = await supabase.from("products").insert({ + // 1. Create Product + const { data: product, error } = await supabase.from("products").insert({ name: data.name, category: data.category, description: data.description, price: data.price, - image_url: data.image_url, - }) + image_url: data.image_url, // Main image (can be first of images) + is_active: data.is_active ?? true + }).select().single() if (error) throw error + // 2. Insert Images (if any) + if (data.images && data.images.length > 0) { + const imageInserts = data.images.map((url, index) => ({ + product_id: product.id, + image_url: url, + display_order: index + })) + + const { error: imgError } = await supabase.from("product_images").insert(imageInserts) + if (imgError) { + console.error("Error inserting images:", imgError) + // We don't throw here to avoid failing the whole product creation if just images fail + } + } + revalidatePath("/dashboard/products") return { success: true } } catch (error) { @@ -40,16 +55,38 @@ export async function updateProduct(id: number, data: ProductData) { const supabase = createClient() try { + // 1. Update Product const { error } = await supabase.from("products").update({ name: data.name, category: data.category, description: data.description, price: data.price, image_url: data.image_url, + is_active: data.is_active }).eq("id", id) if (error) throw error + // 2. Update Images + // Strategy: Delete all and re-insert is simplest for now. + // Or better: Differential update. For simplicity in MVP: Delete all for this product and re-insert *if* new images provided. + // Actually, if we want to keep existing ones, we need more complex logic. + // For now, let's assume the form sends the FULL list of current images. + if (data.images) { + // Delete old + await supabase.from("product_images").delete().eq("product_id", id) + + // Insert new + if (data.images.length > 0) { + const imageInserts = data.images.map((url, index) => ({ + product_id: id, + image_url: url, + display_order: index + })) + await supabase.from("product_images").insert(imageInserts) + } + } + revalidatePath("/dashboard/products") revalidatePath(`/dashboard/products/${id}`) return { success: true } diff --git a/app/(dashboard)/layout.tsx b/app/(dashboard)/layout.tsx index 53d555d..9c0dd6e 100644 --- a/app/(dashboard)/layout.tsx +++ b/app/(dashboard)/layout.tsx @@ -4,6 +4,8 @@ import { redirect } from "next/navigation" import { Sidebar } from "@/components/dashboard/sidebar" import { DashboardHeader } from "@/components/dashboard/header" +import { AutoLogoutHandler } from "@/components/dashboard/auto-logout-handler" + export default async function DashboardLayout({ children, }: Readonly<{ @@ -20,6 +22,7 @@ export default async function DashboardLayout({ return (
+