Files
homaroma/apps/backend/prisma/seed-pages.ts
T
2026-07-19 06:37:42 -04:00

841 lines
24 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 { 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: "PRODUCT_MAIN",
order: 2,
isActive: true,
payload: {}
}
});
// Editorial banner can now be reordered between native product blocks
await prisma.pageSection.create({
data: {
pageId: productDetailPage.id,
type: "EDITORIAL_TILE",
order: 3,
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"
}
}
});
await prisma.pageSection.createMany({
data: [
{
pageId: productDetailPage.id,
type: "PRODUCT_DETAILS",
order: 4,
isActive: true,
payload: { title: "Product Details", showHeading: true },
},
{
pageId: productDetailPage.id,
type: "PRODUCT_SPECS",
order: 5,
isActive: true,
payload: { title: "Specifications", showHeading: true },
},
{
pageId: productDetailPage.id,
type: "RELATED_PRODUCTS",
order: 6,
isActive: true,
payload: { title: "Related Products", showHeading: true, showViewAllLink: true },
},
],
});
// 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();
});