import { PrismaClient } from '@prisma/client'; import { Pool } from 'pg'; import { PrismaPg } from '@prisma/adapter-pg'; const pool = new Pool({ connectionString: process.env.DATABASE_URL }); const adapter = new PrismaPg(pool); const prisma = new PrismaClient({ adapter }); async function main() { console.log("🌱 Seeding Dynamic Page Builder..."); // 1. Create the HomePage const page = await prisma.page.upsert({ where: { slug: "home" }, update: {}, create: { slug: "home", title: "Home Page", isPublished: true, } }); console.log(`βœ… Created page: ${page.title} (slug: ${page.slug})`); // Clear existing sections for home page so we don't duplicate await prisma.pageSection.deleteMany({ where: { pageId: page.id } }); // 2. Create default sections: HERO, CATEGORIES, PRODUCTS, BANNER, TEXT // Section 1: Hero await prisma.pageSection.create({ data: { pageId: page.id, type: "HERO", order: 1, isActive: true, payload: { tagline: "VIBRANT ELEGANCE COLLECTION", title: "Inhale [Serenity]", description: "Crafting premium sensory experiences that transform your space into a sanctuary of peace.", imageUrl: "/images/hero.png", buttonText: "Explore Collection", buttonLink: "/shop" } } }); // Section 2: Categories await prisma.pageSection.create({ data: { pageId: page.id, type: "CATEGORIES", order: 2, isActive: true, payload: { title: "Our Collections", subtitle: "Discover the perfect scent for every moment" } } }); // Section 3: Products (Featured Picks) await prisma.pageSection.create({ data: { pageId: page.id, type: "PRODUCTS", order: 3, isActive: true, payload: { title: "Featured Picks", subtitle: "Hand-picked fragrances recommended just for you", type: "featured", limit: 3 } } }); // Section 4: Banner await prisma.pageSection.create({ data: { pageId: page.id, type: "BANNER", order: 4, isActive: true, payload: { imageUrl: "/images/oil_ozone.png", linkUrl: "/category/1", title: "Special Offer", description: "Get 10% off on your first purchase of Oil Ozone collection", buttonText: "Shop Now" } } }); // Section 5: Text info await prisma.pageSection.create({ data: { pageId: page.id, type: "TEXT", order: 5, isActive: true, payload: { title: "About HomAroma", content: "HomAroma is dedicated to sourcing the finest raw materials to formulate high-quality essential oils, reed diffusers, and room sprays. Our goal is to bring nature's purity directly into your life.", textAlign: "center" } } }); console.log("βœ… Seeded 5 default home page sections successfully!"); // 3. Create the Shop Page Layout const shopPage = await prisma.page.upsert({ where: { slug: "shop-layout" }, update: {}, create: { slug: "shop-layout", title: "Shop Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${shopPage.title} (slug: ${shopPage.slug})`); // Clear existing sections for shop page so we don't duplicate await prisma.pageSection.deleteMany({ where: { pageId: shopPage.id } }); // Shop Section 1: Announcement Bar await prisma.pageSection.create({ data: { pageId: shopPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["[FREE SHIPPING] on orders over ΰΈΏ1,500", "New Premium Collection is out now!"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); // Shop Section 2: Hero Banner (Set to active by default to showcase the header capabilities) await prisma.pageSection.create({ data: { pageId: shopPage.id, type: "HERO", order: 2, isActive: true, payload: { tagline: "CURATED BOTANICALS", title: "The [Shop] Collection", description: "Transform your daily space into a luxury escape with our natural aroma range.", imageUrl: "/images/hero.png", buttonText: "Learn More", buttonLink: "/about" } } }); // Shop Section 3: Editorial Tile await prisma.pageSection.create({ data: { pageId: shopPage.id, type: "EDITORIAL_TILE", order: 3, isActive: true, payload: { title: "Crafted with [Sensory Passion]", description: "Every formulation at HomAroma is a tribute to pure botanical essences, hand-blended to capture nature’s quiet intelligence.", imageUrl: "/images/oil_ozone.png", imagePosition: "right", buttonText: "Read Our Story", buttonLink: "/about", backgroundColor: "#FDFDF9", textColor: "#1F3D2D" } } }); // Shop Section 4: Newsletter await prisma.pageSection.create({ data: { pageId: shopPage.id, type: "NEWSLETTER", order: 4, isActive: true, payload: { title: "Begin Your Wellness Journey", description: "Subscribe to receive 10% off your first purchase and exclusive updates.", buttonText: "Subscribe", placeholderText: "Enter your email address", showPrivacyCheckbox: true, privacyText: "I agree to the privacy policy." } } }); console.log("βœ… Seeded default shop-layout page sections successfully!"); // 4. Create the Scent Guide Page Layout const scentGuidePage = await prisma.page.upsert({ where: { slug: "scent-guide-layout" }, update: {}, create: { slug: "scent-guide-layout", title: "Scent Guide Layout", isPublished: true, } }); console.log(`βœ… Created page: ${scentGuidePage.title} (slug: ${scentGuidePage.slug})`); // Clear existing sections for scent guide page so we don't duplicate await prisma.pageSection.deleteMany({ where: { pageId: scentGuidePage.id } }); // Scent Guide Section 1: Announcement Bar await prisma.pageSection.create({ data: { pageId: scentGuidePage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Explore our Scent Guide to find your signature fragrance", "Read wellness articles crafted by experts"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); // Scent Guide Section 2: Hero Banner await prisma.pageSection.create({ data: { pageId: scentGuidePage.id, type: "HERO", order: 2, isActive: true, payload: { tagline: "JOURNAL & INSIGHTS", title: "The [Scent] Guide", description: "Welcome to the sensory archive of HomAroma. Explore the art and science of botanical aromatherapy.", imageUrl: "/images/hero.png", buttonText: "Read Story", buttonLink: "/about" } } }); // Scent Guide Section 3: Newsletter await prisma.pageSection.create({ data: { pageId: scentGuidePage.id, type: "NEWSLETTER", order: 3, isActive: true, payload: { title: "Stay Inspired", description: "Subscribe to our journal and get regular wellness guides, blending tips, and exclusive offers.", buttonText: "Subscribe", placeholderText: "Enter your email address", showPrivacyCheckbox: true, privacyText: "I agree to the privacy policy." } } }); console.log("βœ… Seeded default scent-guide-layout page sections successfully!"); // 5. Create Category Page Layout const categoryPage = await prisma.page.upsert({ where: { slug: "category-layout" }, update: {}, create: { slug: "category-layout", title: "Category Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${categoryPage.title} (slug: ${categoryPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: categoryPage.id } }); // Announcement Bar for Categories await prisma.pageSection.create({ data: { pageId: categoryPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Explore our specialized collections for your sanctuary", "Free premium shipping on orders over ΰΈΏ1,500"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); // Newsletter at the bottom of Categories await prisma.pageSection.create({ data: { pageId: categoryPage.id, type: "NEWSLETTER", order: 2, isActive: true, payload: { title: "Join [HomAroma] Circle", description: "Subscribe to receive announcements of new single-origin botanical releases.", buttonText: "Subscribe", placeholderText: "Enter your email address", showPrivacyCheckbox: true, privacyText: "I agree to the privacy policy." } } }); // 6. Create Product Detail Page Layout const productDetailPage = await prisma.page.upsert({ where: { slug: "product-detail-layout" }, update: {}, create: { slug: "product-detail-layout", title: "Product Detail Layout", isPublished: true, } }); console.log(`βœ… Created page: ${productDetailPage.title} (slug: ${productDetailPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: productDetailPage.id } }); // Announcement Bar for Product Details await prisma.pageSection.create({ data: { pageId: productDetailPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Special Offer: Get 10% off your first purchase of single-origin oils", "Hand-formulated with pure botanical extracts"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); // Editorial banner at the bottom of Product Details await prisma.pageSection.create({ data: { pageId: productDetailPage.id, type: "EDITORIAL_TILE", order: 2, isActive: true, payload: { title: "The [Botanical] Sourcing", description: "All our raw materials are sustainably harvested at peak potency from verified organic micro-farms worldwide.", imageUrl: "/images/oil_ozone.png", imagePosition: "left", buttonText: "Sourcing Map", buttonLink: "/about", backgroundColor: "#FDFDF9", textColor: "#1F3D2D" } } }); // 7. Create FAQ Page Layout const faqPage = await prisma.page.upsert({ where: { slug: "faq-layout" }, update: {}, create: { slug: "faq-layout", title: "FAQ Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${faqPage.title} (slug: ${faqPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: faqPage.id } }); // Announcement Bar for FAQ await prisma.pageSection.create({ data: { pageId: faqPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Need instant help? Reach out on LINE @homaroma", "FAQ updated for Summer 2026 delivery guidelines"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 4000 } } }); // Newsletter at the bottom of FAQ await prisma.pageSection.create({ data: { pageId: faqPage.id, type: "NEWSLETTER", order: 2, isActive: true, payload: { title: "Stay informed with [HomAroma]", description: "Sign up to receive shipping updates, care guides, and exclusive collection invites.", buttonText: "Subscribe", placeholderText: "Enter your email address", showPrivacyCheckbox: true, privacyText: "I agree to the privacy policy." } } }); console.log("βœ… Seeded default category, product-detail, and FAQ layout sections successfully!"); // 8. Create Wishlist Page Layout const wishlistPage = await prisma.page.upsert({ where: { slug: "wishlist-layout" }, update: {}, create: { slug: "wishlist-layout", title: "Wishlist Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${wishlistPage.title} (slug: ${wishlistPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: wishlistPage.id } }); await prisma.pageSection.create({ data: { pageId: wishlistPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Sign up to HomAroma Circle to get 10% off your wishlist items", "Hand-crafted botanicals shipped directly to you"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); await prisma.pageSection.create({ data: { pageId: wishlistPage.id, type: "NEWSLETTER", order: 2, isActive: true, payload: { title: "Don't lose your favorites", description: "Subscribe to receive price drops, back-in-stock alerts, and exclusive discounts on items in your wishlist.", buttonText: "Subscribe", placeholderText: "Enter your email address", showPrivacyCheckbox: true, privacyText: "I agree to the privacy policy." } } }); // 9. Create Search Page Layout const searchPage = await prisma.page.upsert({ where: { slug: "search-layout" }, update: {}, create: { slug: "search-layout", title: "Search Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${searchPage.title} (slug: ${searchPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: searchPage.id } }); await prisma.pageSection.create({ data: { pageId: searchPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Need help finding something? Live Chat with our scent experts on LINE @homaroma"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); await prisma.pageSection.create({ data: { pageId: searchPage.id, type: "EDITORIAL_TILE", order: 2, isActive: true, payload: { title: "Find Your [Signature Scent]", description: "Aromatherapy is the art of tuning your environment. Discover our curation of room sprays, reed diffusers, and essential oils designed for modern sanctuaries.", imageUrl: "/images/hero.png", imagePosition: "right", buttonText: "Explore Guide", buttonLink: "/scent-guide", backgroundColor: "#FDFDF9", textColor: "#1F3D2D" } } }); // 10. Create Coupons Page Layout const couponsPage = await prisma.page.upsert({ where: { slug: "coupons-layout" }, update: {}, create: { slug: "coupons-layout", title: "Coupons Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${couponsPage.title} (slug: ${couponsPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: couponsPage.id } }); await prisma.pageSection.create({ data: { pageId: couponsPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Enjoy limited-time discount codes for your sensory sanctuary"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); await prisma.pageSection.create({ data: { pageId: couponsPage.id, type: "NEWSLETTER", order: 2, isActive: true, payload: { title: "Get Exclusive Secret Codes", description: "Become a subscriber to get weekly private discount codes and early access to new collections.", buttonText: "Subscribe", placeholderText: "Enter your email address", showPrivacyCheckbox: true, privacyText: "I agree to the privacy policy." } } }); // 11. Create Contact Page Layout const contactPage = await prisma.page.upsert({ where: { slug: "contact-layout" }, update: {}, create: { slug: "contact-layout", title: "Contact Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${contactPage.title} (slug: ${contactPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: contactPage.id } }); await prisma.pageSection.create({ data: { pageId: contactPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Customer support is available Mon-Sat, 9:00 - 18:00 on LINE @homaroma"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 4000 } } }); await prisma.pageSection.create({ data: { pageId: contactPage.id, type: "EDITORIAL_TILE", order: 2, isActive: true, payload: { title: "Our [Bangkok Studio]", description: "Visit our flagship boutique to experience custom blending sessions and smell our full botanical library in person.", imageUrl: "/images/hero.png", imagePosition: "left", buttonText: "Book Session", buttonLink: "/about", backgroundColor: "#FDFDF9", textColor: "#1F3D2D" } } }); // 12. Create Order Success Page Layout const orderSuccessPage = await prisma.page.upsert({ where: { slug: "order-success-layout" }, update: {}, create: { slug: "order-success-layout", title: "Order Success Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${orderSuccessPage.title} (slug: ${orderSuccessPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: orderSuccessPage.id } }); await prisma.pageSection.create({ data: { pageId: orderSuccessPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Thank you for shopping with HomAroma! Your package is preparing.", "Your order tracking status will be updated here."], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); await prisma.pageSection.create({ data: { pageId: orderSuccessPage.id, type: "EDITORIAL_TILE", order: 2, isActive: true, payload: { title: "Crafting Your [Sanctuary]", description: "Every order is carefully packaged by hand using sustainable, biodegradable materials. We ensure your botanicals arrive fresh and ready to enrich your space.", imageUrl: "/images/oil_ozone.png", imagePosition: "right", buttonText: "Our Sustainability Commitments", buttonLink: "/about", backgroundColor: "#FDFDF9", textColor: "#1F3D2D" } } }); // 13. Create Track Order Page Layout const trackOrderPage = await prisma.page.upsert({ where: { slug: "track-order-layout" }, update: {}, create: { slug: "track-order-layout", title: "Track Order Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${trackOrderPage.title} (slug: ${trackOrderPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: trackOrderPage.id } }); await prisma.pageSection.create({ data: { pageId: trackOrderPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Check shipping status live. For any delivery queries, reach LINE @homaroma"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 3000 } } }); await prisma.pageSection.create({ data: { pageId: trackOrderPage.id, type: "EDITORIAL_TILE", order: 2, isActive: true, payload: { title: "Scenting Your [Daily Rituals]", description: "While waiting for your order, explore how different botanical notes impact focus, sleep, and emotional balance in our Scent Guide.", imageUrl: "/images/hero.png", imagePosition: "left", buttonText: "Read Scent Guide", buttonLink: "/scent-guide", backgroundColor: "#FDFDF9", textColor: "#1F3D2D" } } }); console.log("βœ… Seeded default Category, Product Detail, FAQ, Wishlist, Search, Coupons, Contact, Order Success, and Track Order layouts successfully!"); // 14. Create Checkout Page Layout const checkoutPage = await prisma.page.upsert({ where: { slug: "checkout-layout" }, update: {}, create: { slug: "checkout-layout", title: "Checkout Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${checkoutPage.title} (slug: ${checkoutPage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: checkoutPage.id } }); await prisma.pageSection.create({ data: { pageId: checkoutPage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Secure checkout powered by HomAroma β€” all payments are encrypted and protected", "Free shipping on orders over ΰΈΏ1,500"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 4000 } } }); await prisma.pageSection.create({ data: { pageId: checkoutPage.id, type: "EDITORIAL_TILE", order: 2, isActive: true, payload: { title: "Crafted for Your [Sanctuary]", description: "Every HomAroma order is hand-packed with care using eco-conscious materials, so your botanicals arrive in perfect condition.", imageUrl: "/images/oil_ozone.png", imagePosition: "right", buttonText: "Our Sustainability Promise", buttonLink: "/about", backgroundColor: "#FDFDF9", textColor: "#1F3D2D" } } }); // 15. Create Profile Page Layout const profilePage = await prisma.page.upsert({ where: { slug: "profile-layout" }, update: {}, create: { slug: "profile-layout", title: "Profile Page Layout", isPublished: true, } }); console.log(`βœ… Created page: ${profilePage.title} (slug: ${profilePage.slug})`); await prisma.pageSection.deleteMany({ where: { pageId: profilePage.id } }); await prisma.pageSection.create({ data: { pageId: profilePage.id, type: "ANNOUNCEMENT_BAR", order: 1, isActive: true, payload: { slides: ["Welcome back to HomAroma β€” manage your orders and wishlist from your profile", "Earn points with every purchase"], backgroundColor: "#1F3D2D", textColor: "#FDFDF9", speed: 4000 } } }); await prisma.pageSection.create({ data: { pageId: profilePage.id, type: "NEWSLETTER", order: 2, isActive: true, payload: { title: "Exclusive Member Benefits", description: "Subscribe to receive early access to new collections, member-only discounts, and scent guides curated just for you.", buttonText: "Subscribe", placeholderText: "Enter your email address", showPrivacyCheckbox: true, privacyText: "I agree to the privacy policy." } } }); console.log("βœ… Seeded checkout-layout and profile-layout successfully!"); console.log("🌱 All 15 required pages seeded successfully!"); } main() .catch((e) => { console.error("❌ Error seeding page:", e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); await pool.end(); });