Add website slot defaults including leather banner placeholder.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
0f80de1f05
commit
00b5d85f91
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Seed curated homepage images into website slots for mana-collection.
|
||||
* Creates missing cells and fills empty imageUrl with storefront defaults.
|
||||
* Never overwrites an existing uploaded imageUrl.
|
||||
*
|
||||
* Usage: npm run seed:website-slots
|
||||
*/
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { WEBSITE_SLOT_DEFS } from '../src/website-slots/website-slot.catalog';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
type DefaultRow = {
|
||||
slotKey: string;
|
||||
sortOrder: number;
|
||||
nameFa: string;
|
||||
nameEn: string;
|
||||
subtext: string;
|
||||
link: string;
|
||||
imageUrl: string;
|
||||
};
|
||||
|
||||
function collectDefaults(): DefaultRow[] {
|
||||
const rows: DefaultRow[] = [];
|
||||
for (const def of WEBSITE_SLOT_DEFS) {
|
||||
if (def.kind === 'fixed' && def.defaultImage) {
|
||||
rows.push({
|
||||
slotKey: def.slug,
|
||||
sortOrder: 0,
|
||||
nameFa: def.defaultNameFa || def.labelFa,
|
||||
nameEn: def.defaultNameEn || def.labelEn,
|
||||
subtext: def.defaultSubtext || '',
|
||||
link: def.defaultLink || '',
|
||||
imageUrl: def.defaultImage,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (def.kind === 'fixed-set' && def.cellLabels?.length) {
|
||||
def.cellLabels.forEach((cell, index) => {
|
||||
if (!cell.defaultImage) return;
|
||||
rows.push({
|
||||
slotKey: def.slug,
|
||||
sortOrder: index,
|
||||
nameFa: cell.defaultNameFa || cell.labelFa,
|
||||
nameEn: cell.defaultNameEn || cell.labelEn,
|
||||
subtext: cell.defaultSubtext || '',
|
||||
link: cell.defaultLink || '',
|
||||
imageUrl: cell.defaultImage,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const store = await prisma.store.findFirst({
|
||||
where: { slug: 'mana-collection' },
|
||||
select: { id: true, slug: true },
|
||||
});
|
||||
if (!store) {
|
||||
throw new Error('Store mana-collection not found. Run seed:mana-store first.');
|
||||
}
|
||||
|
||||
const defaults = collectDefaults();
|
||||
let created = 0;
|
||||
let filled = 0;
|
||||
let skipped = 0;
|
||||
|
||||
for (const row of defaults) {
|
||||
const existing = await prisma.websiteSlotItem.findFirst({
|
||||
where: {
|
||||
storeId: store.id,
|
||||
slotKey: row.slotKey,
|
||||
sortOrder: row.sortOrder,
|
||||
},
|
||||
});
|
||||
|
||||
if (!existing) {
|
||||
await prisma.websiteSlotItem.create({
|
||||
data: {
|
||||
storeId: store.id,
|
||||
slotKey: row.slotKey,
|
||||
sortOrder: row.sortOrder,
|
||||
nameFa: row.nameFa,
|
||||
nameEn: row.nameEn,
|
||||
subtext: row.subtext,
|
||||
linkText: '',
|
||||
link: row.link,
|
||||
imageUrl: row.imageUrl,
|
||||
},
|
||||
});
|
||||
created += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
const shouldReplaceImage =
|
||||
!existing.imageUrl ||
|
||||
// Replace legacy CDN category icons with curated transparent assets.
|
||||
(row.slotKey === 'category-strip' &&
|
||||
!existing.imageUrl.includes('/images/transparent/')) ||
|
||||
((row.slotKey === 'opening-frame' || row.slotKey === 'sticky-story') &&
|
||||
!existing.imageUrl.includes('/images/landscapes/'));
|
||||
|
||||
if (shouldReplaceImage) {
|
||||
await prisma.websiteSlotItem.update({
|
||||
where: { id: existing.id },
|
||||
data: {
|
||||
imageUrl: row.imageUrl,
|
||||
nameFa: existing.nameFa || row.nameFa,
|
||||
nameEn: existing.nameEn || row.nameEn,
|
||||
subtext: existing.subtext || row.subtext,
|
||||
link: existing.link || row.link,
|
||||
},
|
||||
});
|
||||
filled += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
skipped += 1;
|
||||
}
|
||||
|
||||
console.log('Seeded website slot defaults:', {
|
||||
store: store.slug,
|
||||
created,
|
||||
filledEmptyImages: filled,
|
||||
alreadyHadImages: skipped,
|
||||
totalDefaults: defaults.length,
|
||||
});
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exitCode = 1;
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user