39358-vm/artifacts/api-server/src/routes/store-settings.ts
2026-03-27 02:46:26 +00:00

133 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Router } from "express";
import { db } from "@workspace/db";
import { storeSettingsTable } from "@workspace/db/schema";
const router = Router();
export const DEFAULT_SETTINGS: Record<string, string> = {
// Branding
store_name_ar: "متجر اكسترا",
store_name_en: "eXtra Store",
store_icon: "⚡",
store_logo_url: "",
primary_color: "#f97316",
// Announcement bar
announcement_enabled: "true",
announcement_text: "🎉 شحن مجاني على جميع الطلبات فوق 200 ر.س | عروض حصرية كل يوم",
announcement_text_en: "🎉 Free shipping on all orders over 200 SAR | Exclusive deals every day",
announcement_color: "#f97316",
announcement_text_color: "#ffffff",
// Hero section
hero_enabled: "true",
hero_title_ar: "أفضل الإلكترونيات\nفي المملكة العربية السعودية",
hero_title_en: "Best Electronics\nin Saudi Arabia",
hero_subtitle_ar: "اكتشف أحدث الهواتف، اللابتوبات، الأجهزة المنزلية والمزيد بأسعار لا تُضاهى",
hero_subtitle_en: "Discover the latest phones, laptops, home appliances and more at unbeatable prices",
hero_cta_ar: "تسوق الآن",
hero_cta_en: "Shop Now",
hero_cta_link: "/category/0",
hero_badge_ar: "⚡ عروض حصرية لفترة محدودة",
hero_badge_en: "⚡ Exclusive limited-time offers",
hero_bg_image: "",
hero_accent_color: "#f97316",
// Home sections
section_trending_enabled: "true",
section_trending_title_ar: "الأكثر رواجاً",
section_trending_title_en: "Trending",
section_trending_icon: "🔥",
section_bestseller_enabled: "true",
section_bestseller_title_ar: "الأكثر مبيعاً",
section_bestseller_title_en: "Best Sellers",
section_bestseller_icon: "⭐",
section_new_enabled: "true",
section_new_title_ar: "وصل حديثاً",
section_new_title_en: "New Arrivals",
section_new_icon: "✨",
// Promo banners (JSON array)
promo_banners: "[]",
// Extra categories section
extra_section_enabled: "true",
extra_section_title_ar: "اكسترا — إلكترونيات وأجهزة",
extra_section_title_en: "eXtra — Electronics & Appliances",
// Shein section
shein_section_enabled: "true",
shein_section_title_ar: "أزياء، جمال ومنزل",
shein_section_title_en: "Fashion, Beauty & Home",
// Footer
footer_tagline_ar: "متجرك المفضل للإلكترونيات والأزياء في المملكة",
// Cart & Checkout settings
cart_free_shipping_riyadh: "100",
cart_free_shipping_other: "200",
cart_delivery_fee_riyadh: "15",
cart_delivery_fee_other: "30",
cart_min_order: "0",
cart_max_qty: "10",
cart_banner_enabled: "false",
cart_banner_text: "🚚 التوصيل خلال 2-3 أيام عمل | شحن مجاني فوق 200 ر.س",
cart_banner_color: "#1a1a1a",
cart_payment_mada: "true",
cart_payment_visa: "true",
cart_payment_applepay: "true",
cart_payment_stcpay: "true",
cart_checkout_note: "",
// Delivery page conditions (JSON array)
delivery_conditions: JSON.stringify([
{ id: "1", text: "التوصيل لجميع مناطق المملكة العربية السعودية خلال 37 أيام عمل حسب المدينة.", text_en: "Delivery to all regions of Saudi Arabia within 37 business days depending on the city.", visible: true },
{ id: "2", text: "الشحن مجاني للطلبات التي تتجاوز 200 ر.س.", text_en: "Free shipping on orders over 200 SAR.", visible: true },
{ id: "3", text: "سيتم التواصل معك عبر رقم الجوال لتأكيد الطلب وتحديد موعد التوصيل.", text_en: "We will contact you via mobile to confirm the order and schedule delivery.", visible: true },
{ id: "4", text: "في حال الغياب وقت التوصيل، يُعاد الطلب للمستودع ويُتواصل معك لإعادة الجدولة.", text_en: "If absent during delivery, the order will be returned to the warehouse and we will contact you to reschedule.", visible: true },
{ id: "5", text: "قد تختلف مواعيد التوصيل خلال المواسم والإجازات الرسمية.", text_en: "Delivery times may vary during peak seasons and official holidays.", visible: true }
]),
};
// Public GET — no auth required (storefront reads this)
router.get("/public-settings", async (_req, res) => {
try {
const rows = await db.select().from(storeSettingsTable);
const settings = { ...DEFAULT_SETTINGS };
rows.forEach(r => { settings[r.key] = r.value; });
res.json(settings);
} catch {
res.json(DEFAULT_SETTINGS);
}
});
// Admin GET
router.get("/admin/store-settings", async (_req, res) => {
try {
const rows = await db.select().from(storeSettingsTable);
const settings = { ...DEFAULT_SETTINGS };
rows.forEach(r => { settings[r.key] = r.value; });
res.json(settings);
} catch {
res.status(500).json({ error: "Failed to fetch settings" });
}
});
// Admin PUT
router.put("/admin/store-settings", async (req, res) => {
try {
const updates = req.body as Record<string, string>;
for (const [key, value] of Object.entries(updates)) {
if (typeof value !== "string") continue;
await db.insert(storeSettingsTable)
.values({ key, value })
.onConflictDoUpdate({ target: storeSettingsTable.key, set: { value, updated_at: new Date() } });
}
res.json({ ok: true });
} catch {
res.status(500).json({ error: "Failed to save settings" });
}
});
export default router;