Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
202 lines
5.1 KiB
TypeScript
202 lines
5.1 KiB
TypeScript
import { readFileSync } from 'fs'
|
|
import { join } from 'path'
|
|
|
|
/**
|
|
* Site configuration interface
|
|
*/
|
|
export interface SiteConfig {
|
|
tier: number
|
|
description: string
|
|
manufacturers: string[] | 'all'
|
|
includePaymentComponents: boolean
|
|
minManualCount: number
|
|
}
|
|
|
|
/**
|
|
* Site manufacturer mapping loaded from JSON
|
|
*/
|
|
let siteMappingCache: {
|
|
sites: Record<string, SiteConfig>
|
|
manufacturerAliases: Record<string, string[]>
|
|
} | null = null
|
|
|
|
/**
|
|
* Load site manufacturer mapping from JSON file
|
|
*/
|
|
function loadSiteMapping(): {
|
|
sites: Record<string, SiteConfig>
|
|
manufacturerAliases: Record<string, string[]>
|
|
} {
|
|
if (siteMappingCache !== null) {
|
|
return siteMappingCache
|
|
}
|
|
|
|
try {
|
|
const mappingPath = join(process.cwd(), 'lib', 'site-manufacturer-mapping.json')
|
|
const content = readFileSync(mappingPath, 'utf-8')
|
|
const mapping = JSON.parse(content)
|
|
siteMappingCache = mapping
|
|
return mapping
|
|
} catch (error) {
|
|
console.error('Error loading site manufacturer mapping:', error)
|
|
// Return default configuration for rockymountainvending.com
|
|
return {
|
|
sites: {
|
|
'rockymountainvending.com': {
|
|
tier: 1,
|
|
description: 'Default site configuration',
|
|
manufacturers: ['Crane', 'Royal Vendors', 'GPL', 'AP', 'Dixie-Narco', 'USI', 'Vendo'],
|
|
includePaymentComponents: true,
|
|
minManualCount: 3,
|
|
},
|
|
},
|
|
manufacturerAliases: {},
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the current site domain from environment variable
|
|
* Falls back to rockymountainvending.com if not set
|
|
*/
|
|
export function getSiteDomain(): string {
|
|
return (
|
|
process.env.NEXT_PUBLIC_SITE_DOMAIN ||
|
|
process.env.SITE_DOMAIN ||
|
|
'rockymountainvending.com'
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Get site configuration for a given domain
|
|
*/
|
|
export function getSiteConfig(domain?: string): SiteConfig | null {
|
|
const siteDomain = domain || getSiteDomain()
|
|
const mapping = loadSiteMapping()
|
|
return mapping.sites[siteDomain] || null
|
|
}
|
|
|
|
/**
|
|
* Get allowed manufacturers for a given site domain
|
|
* Returns 'all' for tier 3 sites, or array of manufacturer names for tier 1 and 2
|
|
*/
|
|
export function getAllowedManufacturers(domain?: string): string[] | 'all' {
|
|
const config = getSiteConfig(domain)
|
|
if (!config) {
|
|
// Default to tier 1 manufacturers
|
|
return ['Crane', 'Royal Vendors', 'GPL', 'AP', 'Dixie-Narco', 'USI', 'Vendo']
|
|
}
|
|
|
|
if (config.manufacturers === 'all') {
|
|
return 'all'
|
|
}
|
|
|
|
return config.manufacturers
|
|
}
|
|
|
|
/**
|
|
* Get minimum manual count required per manufacturer for a given site
|
|
*/
|
|
export function getMinManualCount(domain?: string): number {
|
|
const config = getSiteConfig(domain)
|
|
return config?.minManualCount || 3
|
|
}
|
|
|
|
/**
|
|
* Get manufacturer aliases mapping
|
|
* Returns a map of canonical manufacturer names to their aliases
|
|
*/
|
|
export function getManufacturerAliases(): Record<string, string[]> {
|
|
const mapping = loadSiteMapping()
|
|
return mapping.manufacturerAliases || {}
|
|
}
|
|
|
|
/**
|
|
* Check if payment components should be included for a given site
|
|
*/
|
|
export function shouldIncludePaymentComponents(domain?: string): boolean {
|
|
const config = getSiteConfig(domain)
|
|
return config?.includePaymentComponents ?? true
|
|
}
|
|
|
|
/**
|
|
* Get all aliases for a given manufacturer
|
|
* This helps match directory names and filenames to canonical manufacturer names
|
|
*/
|
|
export function getAliasesForManufacturer(manufacturer: string): string[] {
|
|
const aliases = getManufacturerAliases()
|
|
|
|
// First, check if the manufacturer itself is a key
|
|
if (aliases[manufacturer]) {
|
|
return aliases[manufacturer]
|
|
}
|
|
|
|
// Check if the manufacturer matches any alias value
|
|
for (const [canonicalName, aliasList] of Object.entries(aliases)) {
|
|
if (aliasList.includes(manufacturer)) {
|
|
return aliasList
|
|
}
|
|
}
|
|
|
|
// Return the manufacturer itself as the only alias
|
|
return [manufacturer]
|
|
}
|
|
|
|
/**
|
|
* Normalize manufacturer name using aliases
|
|
* Converts directory names like "Royal-Vendors" to canonical "Royal Vendors"
|
|
*/
|
|
export function normalizeManufacturerName(manufacturer: string): string {
|
|
const aliases = getManufacturerAliases()
|
|
|
|
// Check if manufacturer is already a canonical name
|
|
if (aliases[manufacturer]) {
|
|
return manufacturer
|
|
}
|
|
|
|
// Find the canonical name for this manufacturer
|
|
for (const [canonicalName, aliasList] of Object.entries(aliases)) {
|
|
if (aliasList.includes(manufacturer)) {
|
|
return canonicalName
|
|
}
|
|
}
|
|
|
|
// Return as-is if no match found
|
|
return manufacturer
|
|
}
|
|
|
|
/**
|
|
* Check if a manufacturer is allowed for a given site
|
|
*/
|
|
export function isManufacturerAllowed(
|
|
manufacturer: string,
|
|
domain?: string
|
|
): boolean {
|
|
const allowed = getAllowedManufacturers(domain)
|
|
|
|
// Tier 3 sites allow all manufacturers
|
|
if (allowed === 'all') {
|
|
return true
|
|
}
|
|
|
|
// Normalize the manufacturer name
|
|
const normalized = normalizeManufacturerName(manufacturer)
|
|
|
|
// Check if normalized name is in allowed list
|
|
if (allowed.includes(normalized)) {
|
|
return true
|
|
}
|
|
|
|
// Check if any alias matches
|
|
const aliases = getAliasesForManufacturer(normalized)
|
|
for (const alias of aliases) {
|
|
if (allowed.includes(alias)) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
|
|
|