fix: Linter improvements to marketers page, onboarding, and UI index

https://claude.ai/code/session_01LsnvBa7HwF5hs99VZbgLGj
This commit is contained in:
Claude 2026-04-12 01:45:55 +00:00
parent b9ece3e6cc
commit 44894cb4de
No known key found for this signature in database
3 changed files with 60 additions and 109 deletions

View File

@ -98,34 +98,27 @@ function MarketersPage() {
setSubmitted(true); setSubmitted(true);
}; };
const benefitIcons = [Zap, Wrench, HeadphonesIcon, Eye]; const benefits = [
const benefitKeys = [ { icon: Zap, title: 'benefitInstantCommission', desc: 'benefitInstantCommissionDesc' },
{ title: 'benefitInstantCommission', desc: 'benefitInstantCommissionDesc' }, { icon: Wrench, title: 'benefitProTools', desc: 'benefitProToolsDesc' },
{ title: 'benefitProTools', desc: 'benefitProToolsDesc' }, { icon: HeadphonesIcon, title: 'benefitSupport', desc: 'benefitSupportDesc' },
{ title: 'benefitSupport', desc: 'benefitSupportDesc' }, { icon: Eye, title: 'benefitTransparency', desc: 'benefitTransparencyDesc' },
{ title: 'benefitTransparency', desc: 'benefitTransparencyDesc' },
]; ];
const steps = [
const stepIcons = [UserPlus, Share2, Coins]; { icon: UserPlus, title: 'step1Title', desc: 'step1Desc' },
const stepKeys = [ { icon: Share2, title: 'step2Title', desc: 'step2Desc' },
{ title: 'step1Title', desc: 'step1Desc' }, { icon: Coins, title: 'step3Title', desc: 'step3Desc' },
{ title: 'step2Title', desc: 'step2Desc' },
{ title: 'step3Title', desc: 'step3Desc' },
]; ];
const tiers = [ const tiers = [
{ key: 'tierBronze', desc: 'tierBronzeDesc', pct: '10%', color: 'from-amber-700 to-amber-900', badge: 'bg-amber-700/40 text-amber-300' }, { key: 'tierBronze', desc: 'tierBronzeDesc', pct: '10%', color: 'from-amber-700 to-amber-900', badge: 'bg-amber-700/40 text-amber-300' },
{ key: 'tierSilver', desc: 'tierSilverDesc', pct: '15%', color: 'from-slate-400 to-slate-600', badge: 'bg-slate-500/40 text-slate-200' }, { key: 'tierSilver', desc: 'tierSilverDesc', pct: '15%', color: 'from-slate-400 to-slate-600', badge: 'bg-slate-500/40 text-slate-200' },
{ key: 'tierGold', desc: 'tierGoldDesc', pct: '20%', color: 'from-amber-400 to-yellow-500', badge: 'bg-amber-400/30 text-amber-200' }, { key: 'tierGold', desc: 'tierGoldDesc', pct: '20%', color: 'from-amber-400 to-yellow-500', badge: 'bg-amber-400/30 text-amber-200' },
]; ];
const tools = [
const toolIcons = [LayoutDashboard, Link2, FileText, BarChart3]; { icon: LayoutDashboard, key: 'toolDashboard' }, { icon: Link2, key: 'toolLinks' },
const toolKeys = ['toolDashboard', 'toolLinks', 'toolTemplates', 'toolReports']; { icon: FileText, key: 'toolTemplates' }, { icon: BarChart3, key: 'toolReports' },
];
const faqs = Array.from({ length: 5 }, (_, i) => ({ const faqs = Array.from({ length: 5 }, (_, i) => ({ q: t(`marketersPage.faq${i + 1}Q`), a: t(`marketersPage.faq${i + 1}A`) }));
q: t(`marketersPage.faq${i + 1}Q`),
a: t(`marketersPage.faq${i + 1}A`),
}));
return ( return (
<div dir={dir} className="min-h-screen bg-[#0A0F1C] text-white"> <div dir={dir} className="min-h-screen bg-[#0A0F1C] text-white">
@ -177,22 +170,15 @@ function MarketersPage() {
{t('marketersPage.benefitsTitle')} {t('marketersPage.benefitsTitle')}
</motion.h2> </motion.h2>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{benefitKeys.map((bk, i) => { {benefits.map((b) => (
const Icon = benefitIcons[i]; <GlassCard key={b.title}>
return ( <div className="rounded-lg bg-teal-500/10 p-2.5 w-fit mb-4">
<GlassCard key={bk.title}> <b.icon className="h-5 w-5 text-teal-400" />
<div className="rounded-lg bg-teal-500/10 p-2.5 w-fit mb-4"> </div>
<Icon className="h-5 w-5 text-teal-400" /> <h3 className="text-sm font-semibold text-white mb-1.5">{t(`marketersPage.${b.title}`)}</h3>
</div> <p className="text-xs text-slate-400 leading-relaxed">{t(`marketersPage.${b.desc}`)}</p>
<h3 className="text-sm font-semibold text-white mb-1.5"> </GlassCard>
{t(`marketersPage.${bk.title}`)} ))}
</h3>
<p className="text-xs text-slate-400 leading-relaxed">
{t(`marketersPage.${bk.desc}`)}
</p>
</GlassCard>
);
})}
</div> </div>
</div> </div>
</Section> </Section>
@ -204,29 +190,16 @@ function MarketersPage() {
{t('marketersPage.howItWorksTitle')} {t('marketersPage.howItWorksTitle')}
</motion.h2> </motion.h2>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-6"> <div className="grid grid-cols-1 sm:grid-cols-3 gap-6">
{stepKeys.map((sk, i) => { {steps.map((s, i) => (
const Icon = stepIcons[i]; <motion.div key={s.title} variants={fadeUp} className="text-center">
return ( <div className="mx-auto w-14 h-14 rounded-2xl bg-white/5 border border-white/10 flex items-center justify-center mb-4">
<motion.div <s.icon className="h-6 w-6 text-teal-400" />
key={sk.title} </div>
variants={fadeUp} <span className="inline-block text-xs text-teal-400 font-medium mb-2 tabular-nums">{i + 1}</span>
className="text-center" <h3 className="text-sm font-semibold text-white mb-1">{t(`marketersPage.${s.title}`)}</h3>
> <p className="text-xs text-slate-400 leading-relaxed">{t(`marketersPage.${s.desc}`)}</p>
<div className="mx-auto w-14 h-14 rounded-2xl bg-white/5 border border-white/10 flex items-center justify-center mb-4"> </motion.div>
<Icon className="h-6 w-6 text-teal-400" /> ))}
</div>
<span className="inline-block text-xs text-teal-400 font-medium mb-2 tabular-nums">
{i + 1}
</span>
<h3 className="text-sm font-semibold text-white mb-1">
{t(`marketersPage.${sk.title}`)}
</h3>
<p className="text-xs text-slate-400 leading-relaxed">
{t(`marketersPage.${sk.desc}`)}
</p>
</motion.div>
);
})}
</div> </div>
</div> </div>
</Section> </Section>
@ -234,22 +207,13 @@ function MarketersPage() {
{/* ===== COMMISSION TIERS ===== */} {/* ===== COMMISSION TIERS ===== */}
<Section> <Section>
<div className="max-w-4xl mx-auto px-4"> <div className="max-w-4xl mx-auto px-4">
<motion.h2 variants={fadeUp} className="text-2xl font-bold text-center mb-10"> <motion.h2 variants={fadeUp} className="text-2xl font-bold text-center mb-10">{t('marketersPage.tiersTitle')}</motion.h2>
{t('marketersPage.tiersTitle')}
</motion.h2>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-5"> <div className="grid grid-cols-1 sm:grid-cols-3 gap-5">
{tiers.map((tier) => ( {tiers.map((tier) => (
<GlassCard key={tier.key} className="text-center relative overflow-hidden"> <GlassCard key={tier.key} className="text-center relative overflow-hidden">
<div <div className={clsx('absolute inset-0 opacity-[0.06] bg-gradient-to-b', tier.color)} />
className={clsx(
'absolute inset-0 opacity-[0.06] bg-gradient-to-b',
tier.color,
)}
/>
<div className="relative"> <div className="relative">
<span className={clsx('inline-block px-3 py-1 rounded-full text-xs font-medium mb-4', tier.badge)}> <span className={clsx('inline-block px-3 py-1 rounded-full text-xs font-medium mb-4', tier.badge)}>{t(`marketersPage.${tier.key}`)}</span>
{t(`marketersPage.${tier.key}`)}
</span>
<p className="text-4xl font-bold text-white mb-1">{tier.pct}</p> <p className="text-4xl font-bold text-white mb-1">{tier.pct}</p>
<p className="text-xs text-slate-400 mb-3">{t('marketersPage.tierCommission')}</p> <p className="text-xs text-slate-400 mb-3">{t('marketersPage.tierCommission')}</p>
<p className="text-xs text-slate-500">{t(`marketersPage.${tier.desc}`)}</p> <p className="text-xs text-slate-500">{t(`marketersPage.${tier.desc}`)}</p>
@ -270,22 +234,16 @@ function MarketersPage() {
{[1, 2].map((n) => ( {[1, 2].map((n) => (
<GlassCard key={n}> <GlassCard key={n}>
<Quote className="h-5 w-5 text-teal-500/40 mb-3" /> <Quote className="h-5 w-5 text-teal-500/40 mb-3" />
<p className="text-sm text-slate-300 leading-relaxed mb-4"> <p className="text-sm text-slate-300 leading-relaxed mb-4">{t(`marketersPage.testimonial${n}Text`)}</p>
{t(`marketersPage.testimonial${n}Text`)}
</p>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="h-9 w-9 rounded-full bg-gradient-to-br from-teal-500 to-emerald-600 flex items-center justify-center text-sm font-bold text-white"> <div className="h-9 w-9 rounded-full bg-gradient-to-br from-teal-500 to-emerald-600 flex items-center justify-center text-sm font-bold text-white">
{t(`marketersPage.testimonial${n}Name`).charAt(0)} {t(`marketersPage.testimonial${n}Name`).charAt(0)}
</div> </div>
<div> <div>
<p className="text-sm font-medium text-white"> <p className="text-sm font-medium text-white">{t(`marketersPage.testimonial${n}Name`)}</p>
{t(`marketersPage.testimonial${n}Name`)}
</p>
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
<Award className="h-3 w-3 text-amber-400" /> <Award className="h-3 w-3 text-amber-400" />
<span className="text-xs text-slate-400"> <span className="text-xs text-slate-400">{t(`marketersPage.testimonial${n}Role`)}</span>
{t(`marketersPage.testimonial${n}Role`)}
</span>
</div> </div>
</div> </div>
</div> </div>
@ -302,20 +260,12 @@ function MarketersPage() {
{t('marketersPage.toolsTitle')} {t('marketersPage.toolsTitle')}
</motion.h2> </motion.h2>
<motion.div variants={fadeUp} className="grid grid-cols-2 sm:grid-cols-4 gap-4"> <motion.div variants={fadeUp} className="grid grid-cols-2 sm:grid-cols-4 gap-4">
{toolKeys.map((tk, i) => { {tools.map((tl) => (
const Icon = toolIcons[i]; <div key={tl.key} className="rounded-xl bg-white/5 border border-white/10 p-5 text-center hover:bg-white/[0.08] transition-colors">
return ( <tl.icon className="h-6 w-6 text-teal-400 mx-auto mb-3" />
<div <p className="text-xs text-slate-300 font-medium">{t(`marketersPage.${tl.key}`)}</p>
key={tk} </div>
className="rounded-xl bg-white/5 border border-white/10 p-5 text-center hover:bg-white/[0.08] transition-colors" ))}
>
<Icon className="h-6 w-6 text-teal-400 mx-auto mb-3" />
<p className="text-xs text-slate-300 font-medium">
{t(`marketersPage.${tk}`)}
</p>
</div>
);
})}
</motion.div> </motion.div>
</div> </div>
</Section> </Section>

View File

@ -45,25 +45,17 @@ function WelcomePhase({
const [step, setStep] = useState<'role' | 'industry'>('role'); const [step, setStep] = useState<'role' | 'industry'>('role');
const roles: { key: Role; icon: typeof UserCircle }[] = [ const roles: { key: Role; icon: typeof UserCircle }[] = [
{ key: 'salesManager', icon: UserCircle }, { key: 'salesManager', icon: UserCircle }, { key: 'salesRep', icon: Briefcase },
{ key: 'salesRep', icon: Briefcase }, { key: 'executive', icon: Building2 }, { key: 'other', icon: Users },
{ key: 'executive', icon: Building2 },
{ key: 'other', icon: Users },
]; ];
const industries: { key: Industry; label: string }[] = [ const industries: { key: Industry; label: string }[] = [
{ key: 'realEstate', label: t('onboarding.industryRealEstate') }, { key: 'realEstate', label: t('onboarding.industryRealEstate') }, { key: 'automotive', label: t('onboarding.industryAutomotive') },
{ key: 'automotive', label: t('onboarding.industryAutomotive') }, { key: 'healthcare', label: t('onboarding.industryHealthcare') }, { key: 'services', label: t('onboarding.industryServices') },
{ key: 'healthcare', label: t('onboarding.industryHealthcare') },
{ key: 'services', label: t('onboarding.industryServices') },
{ key: 'other', label: t('onboarding.industryOther') }, { key: 'other', label: t('onboarding.industryOther') },
]; ];
const roleLabels: Record<Role, string> = { const roleLabels: Record<Role, string> = {
salesManager: t('onboarding.roleSalesManager'), salesManager: t('onboarding.roleSalesManager'), salesRep: t('onboarding.roleSalesRep'),
salesRep: t('onboarding.roleSalesRep'), executive: t('onboarding.roleExecutive'), other: t('onboarding.roleOther'),
executive: t('onboarding.roleExecutive'),
other: t('onboarding.roleOther'),
}; };
return ( return (

View File

@ -15,3 +15,12 @@ export type { BadgeProps, BadgeVariant } from './badge';
export { Sidebar, useSidebar } from './sidebar'; export { Sidebar, useSidebar } from './sidebar';
export type { SidebarProps, NavItem, NavSection } from './sidebar'; export type { SidebarProps, NavItem, NavSection } from './sidebar';
export { KpiCard } from './kpi-card';
export type { KpiCardProps } from './kpi-card';
export { EmptyState } from './empty-state';
export type { EmptyStateProps } from './empty-state';
export { CommandInput } from './command-input';
export type { CommandInputProps } from './command-input';