Switch the customer app to IRANSans, restyle home featured/newest and cart note sheet, refresh brand icons across apps, and add the PWA install prompt. Co-authored-by: Cursor <cursoragent@cursor.com>
95 lines
3.5 KiB
JavaScript
95 lines
3.5 KiB
JavaScript
/**
|
|
* Generate brand image assets from the icon-only master mark.
|
|
* Usage (from repo root): node scripts/generate-brand-icons.mjs
|
|
*
|
|
* Requires: npm install sharp to-ico (dev/one-off; or already present)
|
|
*/
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import sharp from 'sharp'
|
|
import toIco from 'to-ico'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
const root = path.resolve(__dirname, '..')
|
|
const master = path.join(__dirname, 'brand-assets', 'hedena-icon.webp')
|
|
|
|
if (!fs.existsSync(master)) {
|
|
console.error('Missing master:', master)
|
|
process.exit(1)
|
|
}
|
|
|
|
async function writePng(outPath, size) {
|
|
await fs.promises.mkdir(path.dirname(outPath), { recursive: true })
|
|
await sharp(master)
|
|
.resize(size, size, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 1 } })
|
|
.png()
|
|
.toFile(outPath)
|
|
console.log('wrote', path.relative(root, outPath))
|
|
}
|
|
|
|
async function writeWebp(outPath, size) {
|
|
await fs.promises.mkdir(path.dirname(outPath), { recursive: true })
|
|
await sharp(master)
|
|
.resize(size, size, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 1 } })
|
|
.webp({ quality: 90 })
|
|
.toFile(outPath)
|
|
console.log('wrote', path.relative(root, outPath))
|
|
}
|
|
|
|
async function writeFull(outPath, format) {
|
|
await fs.promises.mkdir(path.dirname(outPath), { recursive: true })
|
|
const pipeline = sharp(master)
|
|
if (format === 'png') await pipeline.png().toFile(outPath)
|
|
else await pipeline.webp({ quality: 90 }).toFile(outPath)
|
|
console.log('wrote', path.relative(root, outPath))
|
|
}
|
|
|
|
async function writeIco(outPath, sizes = [16, 32, 48]) {
|
|
const bufs = await Promise.all(
|
|
sizes.map((s) =>
|
|
sharp(master)
|
|
.resize(s, s, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 1 } })
|
|
.png()
|
|
.toBuffer(),
|
|
),
|
|
)
|
|
const ico = await toIco(bufs)
|
|
await fs.promises.mkdir(path.dirname(outPath), { recursive: true })
|
|
await fs.promises.writeFile(outPath, ico)
|
|
console.log('wrote', path.relative(root, outPath))
|
|
}
|
|
|
|
const userPublic = path.join(root, 'apps/user-app/public')
|
|
const userAssets = path.join(root, 'apps/user-app/src/assets/img')
|
|
const adminPublic = path.join(root, 'apps/admin-panel/public')
|
|
const adminLogo = path.join(root, 'apps/admin-panel/src/assets/images/logo')
|
|
|
|
// Ensure adminPublic exists before writing no-items under it
|
|
await fs.promises.mkdir(path.join(adminPublic, 'img'), { recursive: true })
|
|
|
|
await writeFull(path.join(userPublic, 'img/brand-logo.png'), 'png')
|
|
await writeFull(path.join(userPublic, 'img/brand-logo.webp'), 'webp')
|
|
await writeFull(path.join(userAssets, 'brand-logo.png'), 'png')
|
|
|
|
// Product / missing-image placeholder — same mark
|
|
await writeFull(path.join(userPublic, 'img/no-items.png'), 'png')
|
|
await writeFull(path.join(userAssets, 'no-items.png'), 'png')
|
|
await writeFull(path.join(adminPublic, 'img/no-items.png'), 'png')
|
|
|
|
await writeFull(path.join(adminLogo, 'brand-icon.png'), 'png')
|
|
await writeFull(path.join(adminLogo, 'brand-icon.webp'), 'webp')
|
|
await writeFull(path.join(adminLogo, 'brand-horizontal.png'), 'png')
|
|
|
|
await writePng(path.join(userPublic, 'icon-192.png'), 192)
|
|
await writePng(path.join(userPublic, 'icon-512.png'), 512)
|
|
await writePng(path.join(adminPublic, 'icon-192.png'), 192)
|
|
await writePng(path.join(adminPublic, 'icon-512.png'), 512)
|
|
|
|
await writePng(path.join(adminPublic, 'favicon.png'), 32)
|
|
await writeIco(path.join(userPublic, 'favicon.ico'))
|
|
await writeIco(path.join(adminPublic, 'favicon.ico'))
|
|
await writeIco(path.join(adminLogo, 'favicon.ico'))
|
|
|
|
console.log('done')
|