feat: improve public role pages and help center content
This commit is contained in:
parent
564a383a10
commit
d008cd184d
16 changed files with 3194 additions and 269 deletions
968
src/app.css
968
src/app.css
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,7 @@ export default function PublicFooter() {
|
|||
<img class="public-footer-logo" src="/nxtgauge-logo.png" alt="NXTGAUGE" />
|
||||
<p>© {new Date().getFullYear()} Nxtgauge. All rights reserved.</p>
|
||||
<div class="public-footer-links">
|
||||
<A href="/professionals">Professionals</A>
|
||||
<A href="/terms">Terms</A>
|
||||
<A href="/privacy">Privacy</A>
|
||||
<A href="/help-center">Help Center</A>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ export default function PublicHeader() {
|
|||
|
||||
<div class="desktop-only nav-links">
|
||||
<A class="nav-underline" classList={{ active: isRouteActive(location.pathname, '/') }} href="/">Home</A>
|
||||
<A class="nav-underline" classList={{ active: location.pathname === '/professionals' || location.pathname.startsWith('/professionals/') }} href="/professionals">Professionals</A>
|
||||
<A class="nav-underline" classList={{ active: isRouteActive(location.pathname, '/about') }} href="/about">About Us</A>
|
||||
<A class="nav-underline" classList={{ active: isRouteActive(location.pathname, '/help-center') }} href="/help-center">Help Center</A>
|
||||
<A class="nav-underline" classList={{ active: isRouteActive(location.pathname, '/contact') }} href="/contact">Contact Us</A>
|
||||
|
|
@ -64,6 +65,7 @@ export default function PublicHeader() {
|
|||
<div id="public-mobile-nav" class="mobile-nav">
|
||||
<div class="mobile-nav-links container">
|
||||
<A href="/" onClick={() => setMobileOpen(false)}>Home</A>
|
||||
<A href="/professionals" onClick={() => setMobileOpen(false)}>Professionals</A>
|
||||
<A href="/about" onClick={() => setMobileOpen(false)}>About Us</A>
|
||||
<A href="/help-center" onClick={() => setMobileOpen(false)}>Help Center</A>
|
||||
<A href="/contact" onClick={() => setMobileOpen(false)}>Contact Us</A>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
import { A } from '@solidjs/router';
|
||||
import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js';
|
||||
import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js';
|
||||
import OpportunityGraph from '~/components/OpportunityGraph';
|
||||
import PublicHeader from '~/components/PublicHeader';
|
||||
import PublicFooter from '~/components/PublicFooter';
|
||||
import { professionalPages, professionalSignupHref, type ProfessionalCategory } from '~/lib/professionals';
|
||||
|
||||
type PathCard = {
|
||||
type AudienceCard = {
|
||||
title: string;
|
||||
description: string;
|
||||
button: string;
|
||||
chip: string;
|
||||
icon: 'briefcase' | 'user' | 'users' | 'code' | 'camera' | 'sparkles' | 'grad' | 'film' | 'pen' | 'share' | 'dumbbell' | 'utensils';
|
||||
icon: 'briefcase' | 'user' | 'users' | 'code';
|
||||
href: string;
|
||||
image: string;
|
||||
audience: 'customer' | 'professional' | 'company' | 'job_seeker';
|
||||
|
|
@ -23,127 +24,57 @@ type Flow = {
|
|||
steps: Array<{ title: string; description: string }>;
|
||||
};
|
||||
|
||||
const pathCards: PathCard[] = [
|
||||
const audienceCards: AudienceCard[] = [
|
||||
{
|
||||
title: 'Post a Job',
|
||||
description: 'Create verified job openings and find the right talent faster.',
|
||||
button: 'Start as Company',
|
||||
button: 'Explore Company',
|
||||
chip: 'Company',
|
||||
icon: 'briefcase',
|
||||
href: '/signup?intent=company',
|
||||
href: '/roles/company',
|
||||
audience: 'company',
|
||||
image: 'https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Apply for Jobs',
|
||||
description: 'Build your profile and apply to approved opportunities quickly.',
|
||||
button: 'Start as Job Seeker',
|
||||
button: 'Explore Job Seeker',
|
||||
chip: 'Job Seeker',
|
||||
icon: 'user',
|
||||
href: '/signup?intent=job_seeker',
|
||||
href: '/roles/job-seeker',
|
||||
audience: 'job_seeker',
|
||||
image: 'https://images.unsplash.com/photo-1586281380349-632531db7ed4?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Hire a Professional',
|
||||
description: 'Post your requirement and discover trusted specialists.',
|
||||
button: 'Start as Customer',
|
||||
button: 'Explore Customer',
|
||||
chip: 'Customer',
|
||||
icon: 'users',
|
||||
href: '/signup?intent=customer',
|
||||
href: '/roles/customer',
|
||||
audience: 'customer',
|
||||
image: 'https://images.unsplash.com/photo-1450101499163-c8848c66ca85?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Developer',
|
||||
description: 'Build products and grow with verified client demand.',
|
||||
button: 'Join Developer',
|
||||
title: 'Join as Professional',
|
||||
description: 'Create a trusted profile and grow through verified demand.',
|
||||
button: 'Explore Professionals',
|
||||
chip: 'Professional',
|
||||
icon: 'code',
|
||||
href: '/signup?intent=professional',
|
||||
href: '/professionals',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1498050108023-c5249f4df085?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Photographer',
|
||||
description: 'Capture events and campaigns with trusted bookings.',
|
||||
button: 'Join Photographer',
|
||||
chip: 'Professional',
|
||||
icon: 'camera',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Makeup Artist',
|
||||
description: 'Offer styling services with profile-based trust signals.',
|
||||
button: 'Join Makeup Artist',
|
||||
chip: 'Professional',
|
||||
icon: 'sparkles',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1522335789203-aabd1fc54bc9?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Tutor',
|
||||
description: 'Teach learners and build your reputation with verified profiles.',
|
||||
button: 'Join Tutor',
|
||||
chip: 'Professional',
|
||||
icon: 'grad',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1497633762265-9d179a990aa6?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Video Editor',
|
||||
description: 'Create compelling edits and work with quality clients.',
|
||||
button: 'Join Video Editor',
|
||||
chip: 'Professional',
|
||||
icon: 'film',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1574717024653-61fd2cf4d44d?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Graphic Designer',
|
||||
description: 'Design brand-ready visuals and collaborate with growing businesses.',
|
||||
button: 'Join Graphic Designer',
|
||||
chip: 'Professional',
|
||||
icon: 'pen',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1558655146-d09347e92766?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Social Media Manager',
|
||||
description: 'Plan campaigns and scale audience growth for clients.',
|
||||
button: 'Join Social Manager',
|
||||
chip: 'Professional',
|
||||
icon: 'share',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1611162618071-b39a2ec055fb?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Fitness Trainer',
|
||||
description: 'Coach clients with structured plans and trusted profiles.',
|
||||
button: 'Join Trainer',
|
||||
chip: 'Professional',
|
||||
icon: 'dumbbell',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1517836357463-d25dfeac3438?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
{
|
||||
title: 'Join as Catering Services',
|
||||
description: 'Showcase event-ready menus to customers and companies.',
|
||||
button: 'Join Catering',
|
||||
chip: 'Professional',
|
||||
icon: 'utensils',
|
||||
href: '/signup?intent=professional',
|
||||
audience: 'professional',
|
||||
image: 'https://images.unsplash.com/photo-1555244162-803834f70033?q=80&w=800&auto=format&fit=crop',
|
||||
},
|
||||
];
|
||||
|
||||
const roleFilterOptions: Array<{ key: 'all' | ProfessionalCategory; label: string }> = [
|
||||
{ key: 'all', label: 'All' },
|
||||
{ key: 'creative', label: 'Creative' },
|
||||
{ key: 'tech', label: 'Tech' },
|
||||
{ key: 'education', label: 'Education' },
|
||||
{ key: 'wellness', label: 'Wellness' },
|
||||
{ key: 'events', label: 'Events' },
|
||||
{ key: 'marketing', label: 'Marketing' },
|
||||
];
|
||||
|
||||
const benefits = [
|
||||
|
|
@ -158,8 +89,8 @@ const benefits = [
|
|||
const flows: Flow[] = [
|
||||
{
|
||||
label: 'Customers',
|
||||
title: 'Need to solution, with verified trust in the middle',
|
||||
description: 'Post your requirement, pass quality checks, and receive focused responses.',
|
||||
title: 'Hire trusted professionals with less noise',
|
||||
description: 'Post requirements, pass review checks, and receive better-fit responses.',
|
||||
image: 'https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?q=80&w=1200&auto=format&fit=crop',
|
||||
steps: [
|
||||
{ title: 'Create account', description: 'Sign up quickly with customer intent.' },
|
||||
|
|
@ -170,8 +101,8 @@ const flows: Flow[] = [
|
|||
},
|
||||
{
|
||||
label: 'Professionals',
|
||||
title: 'Profile first, opportunity next',
|
||||
description: 'Build profile quality once, then receive better-fit lead discovery.',
|
||||
title: 'Build trust once, discover better opportunities',
|
||||
description: 'Create a strong profile and respond to verified demand.',
|
||||
image: 'https://images.unsplash.com/photo-1461749280684-dccba630e2f6?q=80&w=1200&auto=format&fit=crop',
|
||||
steps: [
|
||||
{ title: 'Pick role and skills', description: 'Choose service category and specialization.' },
|
||||
|
|
@ -182,8 +113,8 @@ const flows: Flow[] = [
|
|||
},
|
||||
{
|
||||
label: 'Companies',
|
||||
title: 'Hiring workflows without chaos',
|
||||
description: 'Publish requirements, keep quality high, and track applicants clearly.',
|
||||
title: 'Post jobs with approval-based quality control',
|
||||
description: 'Publish openings, keep quality high, and track applicants clearly.',
|
||||
image: 'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=1200&auto=format&fit=crop',
|
||||
steps: [
|
||||
{ title: 'Create company profile', description: 'Set hiring context and org details.' },
|
||||
|
|
@ -194,8 +125,8 @@ const flows: Flow[] = [
|
|||
},
|
||||
{
|
||||
label: 'Job Seekers',
|
||||
title: 'Onboard once, apply with confidence',
|
||||
description: 'Get visible only after approval, then discover jobs with targeted filters.',
|
||||
title: 'Apply to approved opportunities with clarity',
|
||||
description: 'Build your profile and track application progress without confusion.',
|
||||
image: 'https://images.unsplash.com/photo-1450101499163-c8848c66ca85?q=80&w=1200&auto=format&fit=crop',
|
||||
steps: [
|
||||
{ title: 'Set up profile', description: 'Complete essentials and work preferences.' },
|
||||
|
|
@ -225,7 +156,7 @@ const faqs = [
|
|||
},
|
||||
{
|
||||
q: 'Do I need to choose my role during signup?',
|
||||
a: 'Yes. Choose your role first, then we open the correct signup flow for that journey.',
|
||||
a: 'Create one account, then choose and activate the role flow you need.',
|
||||
},
|
||||
] as const;
|
||||
|
||||
|
|
@ -281,20 +212,13 @@ function ChipIcon(props: { kind: (typeof chipNodes)[number]['kind'] }) {
|
|||
);
|
||||
}
|
||||
|
||||
function PathRoleIcon(props: { kind: PathCard['icon'] }) {
|
||||
function PathRoleIcon(props: { kind: AudienceCard['icon'] }) {
|
||||
const common = { fill: 'none', stroke: 'currentColor', 'stroke-width': '2', 'stroke-linecap': 'round', 'stroke-linejoin': 'round' } as const;
|
||||
if (props.kind === 'briefcase') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2" /><path d="M22 13a18 18 0 0 1-20 0" /><rect x="2" y="6" width="20" height="14" rx="2" /></svg>;
|
||||
if (props.kind === 'user') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><circle cx="12" cy="8" r="4" /><path d="M6 20c1.4-3.2 3.4-5 6-5s4.6 1.8 6 5" /></svg>;
|
||||
if (props.kind === 'users') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><path d="M16 3.13a4 4 0 0 1 0 7.75" /></svg>;
|
||||
if (props.kind === 'code') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="m18 16 4-4-4-4" /><path d="m6 8-4 4 4 4" /><path d="m14.5 4-5 16" /></svg>;
|
||||
if (props.kind === 'camera') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="M14 4a2 2 0 0 1 1.76 1.05l.49.9A2 2 0 0 0 18 7h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h2a2 2 0 0 0 1.76-1.05l.49-.9A2 2 0 0 1 10 4z" /><circle cx="12" cy="13" r="3" /></svg>;
|
||||
if (props.kind === 'sparkles') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="M11 2.8a1 1 0 0 1 2 0l1 5.6a2 2 0 0 0 1.6 1.6l5.6 1a1 1 0 0 1 0 2l-5.6 1a2 2 0 0 0-1.6 1.6l-1 5.6a1 1 0 0 1-2 0l-1-5.6A2 2 0 0 0 8.4 14l-5.6-1a1 1 0 0 1 0-2l5.6-1A2 2 0 0 0 10 8.4z" /><path d="M20 2v4M22 4h-4" /></svg>;
|
||||
if (props.kind === 'grad') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="m22 10-10-5-10 5 10 5 10-5z" /><path d="M6 12v5c3 2 9 2 12 0v-5" /></svg>;
|
||||
if (props.kind === 'film') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><rect x="2" y="2" width="20" height="20" rx="2" /><path d="M7 2v20M17 2v20M2 7h20M2 17h20" /></svg>;
|
||||
if (props.kind === 'pen') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="M12 20h9" /><path d="m16.5 3.5 4 4L7 21H3v-4z" /></svg>;
|
||||
if (props.kind === 'share') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><circle cx="18" cy="5" r="3" /><circle cx="6" cy="12" r="3" /><circle cx="18" cy="19" r="3" /><path d="M8.6 13.4 15.4 17M15.4 7 8.6 10.6" /></svg>;
|
||||
if (props.kind === 'dumbbell') return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="M6 10v4M4 9v6M2 8v8M18 10v4M20 9v6M22 8v8M6 12h12" /></svg>;
|
||||
return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="M3 4h18" /><path d="M6 4v16h12V4" /><path d="M9 10h6M9 14h6" /></svg>;
|
||||
return <svg viewBox="0 0 24 24" aria-hidden="true" {...common}><path d="m18 16 4-4-4-4" /><path d="m6 8-4 4 4 4" /><path d="m14.5 4-5 16" /></svg>;
|
||||
}
|
||||
|
||||
function CheckBadgeIcon() {
|
||||
|
|
@ -358,10 +282,7 @@ export default function PublicLanding() {
|
|||
const [reduceMotion, setReduceMotion] = createSignal(false);
|
||||
const [scrollY, setScrollY] = createSignal(0);
|
||||
const [heroTilt, setHeroTilt] = createSignal({ x: 0, y: 0 });
|
||||
const [pathPage, setPathPage] = createSignal(0);
|
||||
const [cardsPerPage, setCardsPerPage] = createSignal(3);
|
||||
const [pathPaused, setPathPaused] = createSignal(false);
|
||||
const [pathTouchStartX, setPathTouchStartX] = createSignal<number | null>(null);
|
||||
const [roleFilter, setRoleFilter] = createSignal<'all' | ProfessionalCategory>('all');
|
||||
const [benefitIdx, setBenefitIdx] = createSignal(0);
|
||||
const [flowIndex, setFlowIndex] = createSignal(0);
|
||||
const [flowStepIndex, setFlowStepIndex] = createSignal(0);
|
||||
|
|
@ -385,23 +306,8 @@ export default function PublicLanding() {
|
|||
});
|
||||
};
|
||||
|
||||
const syncCardsPerPage = () => {
|
||||
const w = window.innerWidth;
|
||||
if (w < 640) {
|
||||
setCardsPerPage(1);
|
||||
return;
|
||||
}
|
||||
if (w < 1024) {
|
||||
setCardsPerPage(2);
|
||||
return;
|
||||
}
|
||||
setCardsPerPage(3);
|
||||
};
|
||||
|
||||
onScroll();
|
||||
syncCardsPerPage();
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
window.addEventListener('resize', syncCardsPerPage);
|
||||
media.addEventListener('change', syncMotion);
|
||||
|
||||
const benefitTimer = window.setInterval(() => setBenefitIdx((x) => (x + 1) % benefits.length), 4200);
|
||||
|
|
@ -417,37 +323,16 @@ export default function PublicLanding() {
|
|||
|
||||
onCleanup(() => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('resize', syncCardsPerPage);
|
||||
media.removeEventListener('change', syncMotion);
|
||||
window.clearInterval(benefitTimer);
|
||||
window.clearInterval(flowTimer);
|
||||
});
|
||||
});
|
||||
|
||||
const pagedPaths = createMemo(() => {
|
||||
const cards = pathCards;
|
||||
const per = cardsPerPage();
|
||||
const pages: PathCard[][] = [];
|
||||
for (let i = 0; i < cards.length; i += per) pages.push(cards.slice(i, i + per));
|
||||
return pages;
|
||||
});
|
||||
|
||||
const activePathPage = createMemo(() => {
|
||||
const pages = pagedPaths();
|
||||
if (pages.length === 0) return 0;
|
||||
return pathPage() % pages.length;
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
const pagesLen = pagedPaths().length;
|
||||
if (reduceMotion() || pathPaused() || pagesLen <= 1) return;
|
||||
const timer = window.setInterval(() => {
|
||||
setPathPage((prev) => {
|
||||
const next = prev + 1;
|
||||
return next >= pagesLen ? 0 : next;
|
||||
});
|
||||
}, 4200);
|
||||
onCleanup(() => window.clearInterval(timer));
|
||||
const visibleProfessionalCards = createMemo(() => {
|
||||
const filtered = roleFilter() === 'all'
|
||||
? professionalPages
|
||||
: professionalPages.filter((item) => item.category === roleFilter());
|
||||
return filtered.slice(0, 8);
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
@ -484,14 +369,15 @@ export default function PublicLanding() {
|
|||
>
|
||||
<div class="container lp-hero-grid">
|
||||
<div>
|
||||
<h1 class="lp-hero-title">Hire verified professionals. Post jobs. Get approvals in 24-48 hours.</h1>
|
||||
<h1 class="lp-hero-title">Trusted hiring and opportunities, verified.</h1>
|
||||
<p class="lp-hero-copy">
|
||||
Nxtgauge connects customers, companies, job seekers, and professionals through a trusted approval workflow.
|
||||
Hire trusted professionals, post verified jobs, and apply faster in one platform.
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<A class="lp-primary-btn" href="/signup?intent=customer">Hire a Professional</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href="/signup?intent=job_seeker">Apply for Jobs</A>
|
||||
<A class="lp-primary-btn" href="/signup?intent=customer">Get Started</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href="#how-it-works">How It Works</A>
|
||||
</div>
|
||||
<p class="lp-hero-note">Most profile and listing reviews are completed within 24-48 hours.</p>
|
||||
</div>
|
||||
<div
|
||||
class="lp-hero-graph"
|
||||
|
|
@ -508,89 +394,75 @@ export default function PublicLanding() {
|
|||
<div class="container panel choose-path-panel">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Choose Your Path</h2>
|
||||
<p class="sub">One account, multiple journeys. Pick your goal and get started.</p>
|
||||
</div>
|
||||
<div class="lp-path-controls desktop-only">
|
||||
<button
|
||||
class="lp-path-arrow"
|
||||
onClick={() => setPathPage((x) => Math.max(0, x - 1))}
|
||||
aria-label="Previous cards"
|
||||
disabled={activePathPage() === 0}
|
||||
>
|
||||
←
|
||||
</button>
|
||||
<button
|
||||
class="lp-path-arrow"
|
||||
onClick={() => setPathPage((x) => Math.min(Math.max(0, pagedPaths().length - 1), x + 1))}
|
||||
aria-label="Next cards"
|
||||
disabled={activePathPage() >= Math.max(0, pagedPaths().length - 1)}
|
||||
>
|
||||
→
|
||||
</button>
|
||||
<h2>Who Nxtgauge is for</h2>
|
||||
<p class="sub">Start with one account, then activate the journey you need.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="path-carousel-shell">
|
||||
<div
|
||||
class={`path-carousel-track ${pathPaused() ? 'path-carousel-track-hover' : ''}`}
|
||||
style={{ transform: `translate3d(-${activePathPage() * 100}%, 0, 0)` }}
|
||||
onMouseEnter={() => setPathPaused(true)}
|
||||
onMouseLeave={() => setPathPaused(false)}
|
||||
onTouchStart={(event) => {
|
||||
setPathPaused(true);
|
||||
setPathTouchStartX(event.changedTouches[0]?.clientX ?? null);
|
||||
}}
|
||||
onTouchEnd={(event) => {
|
||||
setPathPaused(false);
|
||||
const startX = pathTouchStartX();
|
||||
const endX = event.changedTouches[0]?.clientX ?? null;
|
||||
if (startX == null || endX == null) return;
|
||||
const deltaX = endX - startX;
|
||||
if (Math.abs(deltaX) < 40) return;
|
||||
if (deltaX < 0) {
|
||||
setPathPage((x) => Math.min(Math.max(0, pagedPaths().length - 1), x + 1));
|
||||
return;
|
||||
}
|
||||
setPathPage((x) => Math.max(0, x - 1));
|
||||
}}
|
||||
>
|
||||
<For each={pagedPaths()}>
|
||||
{(group) => (
|
||||
<div class="path-page">
|
||||
<div class={`path-grid path-grid-${cardsPerPage()}`}>
|
||||
<For each={group}>
|
||||
{(card) => (
|
||||
<article class="path-card path-card-hero">
|
||||
<div class="path-media">
|
||||
<img src={card.image} alt={card.title} loading="lazy" />
|
||||
<div class="path-media-overlay" />
|
||||
</div>
|
||||
<div class="path-body">
|
||||
<div class="path-head-row">
|
||||
<span class="path-icon"><PathRoleIcon kind={card.icon} /></span>
|
||||
<span class="path-chip"><CheckBadgeIcon />{card.chip}</span>
|
||||
</div>
|
||||
<h3>{card.title}</h3>
|
||||
<p>{card.description}</p>
|
||||
<A class="path-secondary-btn" href={card.href}>{card.button}</A>
|
||||
</div>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
<div class="path-grid">
|
||||
<For each={audienceCards}>
|
||||
{(card) => (
|
||||
<article class="path-card path-card-hero">
|
||||
<div class="path-media">
|
||||
<img src={card.image} alt={card.title} loading="lazy" />
|
||||
<div class="path-media-overlay" />
|
||||
</div>
|
||||
<div class="path-body">
|
||||
<div class="path-head-row">
|
||||
<span class="path-icon"><PathRoleIcon kind={card.icon} /></span>
|
||||
<span class="path-chip"><CheckBadgeIcon />{card.chip}</span>
|
||||
</div>
|
||||
<h3>{card.title}</h3>
|
||||
<p>{card.description}</p>
|
||||
<A class="path-secondary-btn" href={card.href}>{card.button}</A>
|
||||
</div>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="professionals" class="public-section scene-dark lp-section">
|
||||
<div class="container panel choose-path-panel">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Explore professional categories</h2>
|
||||
</div>
|
||||
<A class="path-secondary-btn lp-view-all-btn" href="/professionals">View all professionals</A>
|
||||
</div>
|
||||
<div class="filter-row">
|
||||
<For each={roleFilterOptions}>
|
||||
{(filter) => (
|
||||
<button
|
||||
type="button"
|
||||
class={`chip-btn ${roleFilter() === filter.key ? 'active' : ''}`}
|
||||
onClick={() => setRoleFilter(filter.key)}
|
||||
>
|
||||
{filter.label}
|
||||
</button>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div class="path-grid">
|
||||
<For each={visibleProfessionalCards()}>
|
||||
{(item) => (
|
||||
<article class="path-card path-card-hero">
|
||||
<div class="path-media">
|
||||
<img src={item.image} alt={item.shortTitle} loading="lazy" />
|
||||
<div class="path-media-overlay" />
|
||||
</div>
|
||||
<div class="path-body">
|
||||
<div class="path-head-row">
|
||||
<span class="path-chip">{item.category}</span>
|
||||
</div>
|
||||
<h3>{item.shortTitle}</h3>
|
||||
<p>{item.heroDescription}</p>
|
||||
<div class="lp-role-cta-grid">
|
||||
<A class="path-secondary-btn" href={`/professionals/${item.slug}`}>Explore {item.shortTitle}</A>
|
||||
<A class="path-secondary-btn" href={professionalSignupHref(item.roleKey)}>Join {item.shortTitle}</A>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lp-path-dots">
|
||||
<For each={pagedPaths()}>
|
||||
{(_, idx) => (
|
||||
<button
|
||||
class={`lp-path-dot ${idx() === activePathPage() ? 'active' : ''}`}
|
||||
onClick={() => setPathPage(idx())}
|
||||
aria-label={`Go to page ${idx() + 1}`}
|
||||
/>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
|
|
@ -713,12 +585,12 @@ export default function PublicLanding() {
|
|||
<div class="cta-glow" />
|
||||
<div class="cta-copy">
|
||||
<p class="eyebrow">Quick Actions</p>
|
||||
<h2>Ready to get started?</h2>
|
||||
<p class="sub">Pick your next action and continue with the correct role flow.</p>
|
||||
<h2>Start with one account. Choose your path after.</h2>
|
||||
<p class="sub">Hire, post, apply, or join as a professional from stable role-specific pages.</p>
|
||||
</div>
|
||||
<div class="hero-actions cta-actions">
|
||||
<A class="lp-primary-btn pulse" href="/signup?intent=customer">Hire a Professional</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href="/signup?intent=job_seeker">Apply for Jobs</A>
|
||||
<A class="lp-primary-btn pulse" href="/signup?intent=customer">Get Started</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href="/professionals">Explore Professionals</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href="/signup?intent=company">Post a Job</A>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
458
src/components/RoleLandingPage.tsx
Normal file
458
src/components/RoleLandingPage.tsx
Normal file
|
|
@ -0,0 +1,458 @@
|
|||
import { Meta, Title } from '@solidjs/meta';
|
||||
import { A } from '@solidjs/router';
|
||||
import { For, Show, createMemo, createSignal, onCleanup, onMount } from 'solid-js';
|
||||
import PublicFooter from '~/components/PublicFooter';
|
||||
import PublicHeader from '~/components/PublicHeader';
|
||||
import {
|
||||
getRoleLandingBySlug,
|
||||
roleChecklist,
|
||||
roleOutcomes,
|
||||
roleTrustChips,
|
||||
type RoleLandingAudience,
|
||||
} from '~/lib/role-landings';
|
||||
|
||||
const chipNodes = [
|
||||
{ left: '8%', top: '20%', size: 34, cls: 'lp-chip-slow', label: '★' },
|
||||
{ left: '22%', top: '9%', size: 40, cls: 'lp-chip-mid', label: '✓' },
|
||||
{ left: '88%', top: '16%', size: 36, cls: 'lp-chip-fast', label: '↗' },
|
||||
{ left: '76%', top: '38%', size: 30, cls: 'lp-chip-mid', label: '✦' },
|
||||
{ left: '14%', top: '58%', size: 38, cls: 'lp-chip-fast', label: '⚑' },
|
||||
{ left: '62%', top: '72%', size: 34, cls: 'lp-chip-slow', label: '⎈' },
|
||||
{ left: '42%', top: '84%', size: 30, cls: 'lp-chip-mid', label: '✓' },
|
||||
] as const;
|
||||
|
||||
type Props = {
|
||||
slug: string;
|
||||
pathBase: '/professionals' | '/roles';
|
||||
audience?: RoleLandingAudience;
|
||||
};
|
||||
|
||||
function splitLine(line: string): { title: string; body: string } {
|
||||
const [title, ...rest] = line.split(' - ');
|
||||
return { title, body: rest.join(' - ') };
|
||||
}
|
||||
|
||||
function SectionGlyph(props: { kind: 'trust' | 'visibility' | 'tracking' | 'benefit' | 'work' | 'expectation' | 'why' | 'check' | 'outcome' }) {
|
||||
const stroke = 'currentColor';
|
||||
if (props.kind === 'tracking') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 6v6l4 2" fill="none" stroke={stroke} stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<circle cx="12" cy="12" r="9" fill="none" stroke={stroke} stroke-width="2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (props.kind === 'visibility') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6Z" fill="none" stroke={stroke} stroke-width="2" />
|
||||
<circle cx="12" cy="12" r="3" fill="none" stroke={stroke} stroke-width="2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (props.kind === 'work') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M4 7h16v11H4z" fill="none" stroke={stroke} stroke-width="2" />
|
||||
<path d="M8 7V5h8v2" fill="none" stroke={stroke} stroke-width="2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (props.kind === 'expectation') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 3 4 7v6c0 4 3 7 8 8 5-1 8-4 8-8V7Z" fill="none" stroke={stroke} stroke-width="2" />
|
||||
<path d="m9 12 2 2 4-4" fill="none" stroke={stroke} stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (props.kind === 'why') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 2 14.8 8l6.2.7-4.6 4.3 1.2 6.1L12 16l-5.6 3.1 1.2-6.1L3 8.7 9.2 8Z" fill="none" stroke={stroke} stroke-width="2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (props.kind === 'check') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="9" fill="none" stroke={stroke} stroke-width="2" />
|
||||
<path d="m8 12 2.5 2.5L16 9" fill="none" stroke={stroke} stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (props.kind === 'outcome') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M6 17 18 5" fill="none" stroke={stroke} stroke-width="2" stroke-linecap="round" />
|
||||
<path d="M11 5h7v7" fill="none" stroke={stroke} stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (props.kind === 'benefit') {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 3 21 12l-9 9-9-9Z" fill="none" stroke={stroke} stroke-width="2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M12 3 4 7v6c0 4 3 7 8 8 5-1 8-4 8-8V7Z" fill="none" stroke={stroke} stroke-width="2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default function RoleLandingPage(props: Props) {
|
||||
const [scrollY, setScrollY] = createSignal(0);
|
||||
const [reduceMotion, setReduceMotion] = createSignal(false);
|
||||
const [activeHowStep, setActiveHowStep] = createSignal(0);
|
||||
const [openFaqIdx, setOpenFaqIdx] = createSignal(0);
|
||||
const content = createMemo(() => {
|
||||
const item = getRoleLandingBySlug(String(props.slug || ''));
|
||||
if (!item) return undefined;
|
||||
if (props.audience && item.audience !== props.audience) return undefined;
|
||||
return item;
|
||||
});
|
||||
|
||||
const canonical = createMemo(() => `https://test121.nxtgauge.com${props.pathBase}/${encodeURIComponent(String(props.slug || ''))}`);
|
||||
const pageTitle = createMemo(() => (content() ? `${content()!.shortTitle} | Nxtgauge` : 'Role | Nxtgauge'));
|
||||
const pageDescription = createMemo(() =>
|
||||
content() ? `${content()!.heroDescription} Most role reviews complete in 24-48 hours.` : 'Role landing page on Nxtgauge.'
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
const media = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
const sync = () => setReduceMotion(media.matches);
|
||||
sync();
|
||||
const onScroll = () => setScrollY(window.scrollY || 0);
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
media.addEventListener('change', sync);
|
||||
const timer = window.setInterval(() => {
|
||||
if (media.matches) return;
|
||||
const count = content()?.howItWorksSteps.length || 0;
|
||||
if (count <= 1) return;
|
||||
setActiveHowStep((prev) => (prev + 1) % count);
|
||||
}, 2600);
|
||||
onCleanup(() => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
media.removeEventListener('change', sync);
|
||||
window.clearInterval(timer);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<main class="lp-main">
|
||||
<Title>{pageTitle()}</Title>
|
||||
<Meta name="description" content={pageDescription()} />
|
||||
<Meta property="og:title" content={pageTitle()} />
|
||||
<Meta property="og:description" content={pageDescription()} />
|
||||
<Meta property="og:type" content="website" />
|
||||
<Meta property="og:url" content={canonical()} />
|
||||
<Meta name="twitter:card" content="summary_large_image" />
|
||||
<Meta name="twitter:title" content={pageTitle()} />
|
||||
<Meta name="twitter:description" content={pageDescription()} />
|
||||
<link rel="canonical" href={canonical()} />
|
||||
|
||||
<div class="lp-bg" aria-hidden="true">
|
||||
<div class="lp-dark-base" />
|
||||
<div class="lp-mesh" style={{ transform: `translate3d(0, ${reduceMotion() ? 0 : Math.min(34, scrollY() * 0.1)}px, 0)` }} />
|
||||
<div class="lp-ribbon" style={{ transform: `translate3d(0, ${reduceMotion() ? 0 : Math.min(56, scrollY() * 0.16)}px, 0)` }} />
|
||||
<div class="lp-chips" style={{ transform: `translate3d(0, ${reduceMotion() ? 0 : Math.min(80, scrollY() * 0.22)}px, 0)` }}>
|
||||
<For each={chipNodes}>
|
||||
{(chip) => (
|
||||
<span class={`lp-chip ${chip.cls}`} style={{ left: chip.left, top: chip.top, width: `${chip.size}px`, height: `${chip.size}px` }}>
|
||||
<span class="pro-detail-bg-chip-icon">{chip.label}</span>
|
||||
</span>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div class="lp-noise" />
|
||||
</div>
|
||||
|
||||
<div class="lp-content">
|
||||
<PublicHeader />
|
||||
|
||||
<Show
|
||||
when={content()}
|
||||
fallback={
|
||||
<section class="public-section lp-section">
|
||||
<div class="container panel choose-path-panel">
|
||||
<h2>Role landing page not found</h2>
|
||||
<p class="sub">The requested role page is unavailable.</p>
|
||||
<A class="lp-primary-btn" href="/professionals">Back to Professionals</A>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
>
|
||||
{(item) => (
|
||||
<>
|
||||
<section class="public-section lp-section-hero">
|
||||
<div class="container lp-hero-grid">
|
||||
<div>
|
||||
<p class="eyebrow">{item().heroEyebrow}</p>
|
||||
<h1 class="lp-hero-title">{item().heroTitle}</h1>
|
||||
<p class="lp-hero-copy">{item().heroDescription}</p>
|
||||
<div class="hero-actions">
|
||||
<A class="lp-primary-btn" href={item().primaryCta.href}>{item().primaryCta.label}</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href={item().secondaryCta.href}>{item().secondaryCta.label}</A>
|
||||
</div>
|
||||
<div class="pro-trust-chips">
|
||||
<For each={roleTrustChips}>
|
||||
{(line) => <span>{line}</span>}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lp-hero-graph">
|
||||
<img src={item().heroImage} alt={item().shortTitle} class="role-hero-photo" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="public-section lp-section">
|
||||
<div class="container panel choose-path-panel">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>{item().whatYouGetTitle}</h2>
|
||||
<p class="sub">{item().whatYouGetSubtitle}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="path-grid">
|
||||
<For each={item().whatYouGetCards}>
|
||||
{(line, idx) => (
|
||||
<article class="path-card role-copy-card">
|
||||
<div class="path-body">
|
||||
<div class="path-head-row">
|
||||
<span class="role-chip-icon"><SectionGlyph kind="benefit" /></span>
|
||||
<span class="path-chip">Benefit {String(idx() + 1).padStart(2, '0')}</span>
|
||||
</div>
|
||||
<h3>{splitLine(line).title}</h3>
|
||||
<p>{splitLine(line).body}</p>
|
||||
</div>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="public-section lp-section role-typical-section">
|
||||
<div class="container panel choose-path-panel role-typical-shell">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Typical work and expectations</h2>
|
||||
<p class="sub">Show clients exactly what you handle and what they should confirm before first contact.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pro-real-grid">
|
||||
<article class="pro-real-card role-typical-card">
|
||||
<div class="role-section-headline">
|
||||
<span class="role-card-icon role-card-icon-light"><SectionGlyph kind="work" /></span>
|
||||
<div>
|
||||
<p class="role-section-kicker">Project Scope</p>
|
||||
<h3>{item().typicalLeftTitle}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="role-typical-list">
|
||||
<For each={item().typicalLeftItems}>
|
||||
{(line) => (
|
||||
<li>
|
||||
<span class="role-typical-bullet">•</span>
|
||||
<span>{line}</span>
|
||||
</li>
|
||||
)}
|
||||
</For>
|
||||
</ul>
|
||||
</article>
|
||||
<article class="pro-real-card role-typical-card">
|
||||
<div class="role-section-headline">
|
||||
<span class="role-card-icon role-card-icon-light"><SectionGlyph kind="expectation" /></span>
|
||||
<div>
|
||||
<p class="role-section-kicker">Buyer Evaluation</p>
|
||||
<h3>{item().typicalRightTitle}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="role-typical-list">
|
||||
<For each={item().typicalRightItems}>
|
||||
{(line) => (
|
||||
<li>
|
||||
<span class="role-typical-bullet">•</span>
|
||||
<span>{line}</span>
|
||||
</li>
|
||||
)}
|
||||
</For>
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
<div class="pro-real-note-card">
|
||||
<span class="role-card-icon role-card-icon-light"><SectionGlyph kind="check" /></span>
|
||||
<p>
|
||||
Profiles that clearly explain who you help, how your process works, and what clients receive tend to get faster replies and better-fit inquiries.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="public-section lp-section">
|
||||
<div class="container panel choose-path-panel">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>{item().howItWorksTitle}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<article class="hiwCodeCard">
|
||||
<div class="hiwCodeMedia">
|
||||
<div class="hiwCodeBigRect">
|
||||
<img class="hiwCodePhoto" src={item().heroImage} alt={item().shortTitle} />
|
||||
</div>
|
||||
<div class="hiwCodeMediaCopy">
|
||||
<p class="hiwCodeKicker">{item().shortTitle}</p>
|
||||
<h3 class="hiwCodeTitle">{item().howItWorksTitle}</h3>
|
||||
<p class="hiwCodeDesc">Simple four-step onboarding with trust checkpoints and clearer status visibility.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hiwCodeBody">
|
||||
<p class="hiwCodeStepsHeading">Step Flow</p>
|
||||
<div class="hiwCodeSteps">
|
||||
<For each={item().howItWorksSteps}>
|
||||
{(step, idx) => (
|
||||
<div class={`hiwCodeStep ${idx() === activeHowStep() ? 'hiwCodeStepActive' : ''}`}>
|
||||
<span class="hiwCodeStepNum">{idx() + 1}</span>
|
||||
<div>
|
||||
<h4 class="hiwCodeStepTitle">{step.title}</h4>
|
||||
<p class="hiwCodeStepDesc">{step.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="public-section lp-section">
|
||||
<div class="container panel panel-dark">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>{item().whyChooseTitle}</h2>
|
||||
<p class="sub">Trust-led workflow advantages that improve consistency and first-contact confidence.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="benefit-grid">
|
||||
<For each={item().whyChooseCards}>
|
||||
{(line, idx) => (
|
||||
<article class="benefit-card">
|
||||
<div class="benefit-head">
|
||||
<span class="role-card-icon role-card-icon-dark"><SectionGlyph kind="why" /></span>
|
||||
<span class="benefit-index">Advantage {String(idx() + 1).padStart(2, '0')}</span>
|
||||
</div>
|
||||
<h3>{splitLine(line).title}</h3>
|
||||
<span class="benefit-divider" />
|
||||
<p>{splitLine(line).body}</p>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="public-section lp-section">
|
||||
<div class="container panel choose-path-panel">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Getting started checklist</h2>
|
||||
<p class="sub">Use this launch sequence to improve profile quality and conversion outcomes from day one.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="launch-grid">
|
||||
<article class="launch-panel">
|
||||
<div class="launch-panel-head">
|
||||
<span class="role-card-icon role-card-icon-light"><SectionGlyph kind="check" /></span>
|
||||
<div>
|
||||
<p class="launch-kicker">Checklist</p>
|
||||
<h3>Complete these first</h3>
|
||||
</div>
|
||||
</div>
|
||||
<ol class="launch-list">
|
||||
<For each={roleChecklist}>
|
||||
{(line, idx) => (
|
||||
<li>
|
||||
<span class="launch-step">{String(idx() + 1).padStart(2, '0')}</span>
|
||||
<p>{line}</p>
|
||||
</li>
|
||||
)}
|
||||
</For>
|
||||
</ol>
|
||||
</article>
|
||||
<article class="launch-panel launch-panel-outcomes">
|
||||
<div class="launch-panel-head">
|
||||
<span class="role-card-icon role-card-icon-light"><SectionGlyph kind="outcome" /></span>
|
||||
<div>
|
||||
<p class="launch-kicker">Outcomes</p>
|
||||
<h3>Platform outcomes you can expect</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="outcome-grid">
|
||||
<For each={roleOutcomes}>
|
||||
{(line) => (
|
||||
<article class="outcome-tile">
|
||||
<span class="outcome-dot" />
|
||||
<p>{line}</p>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="public-section lp-section landing-faq-section">
|
||||
<div class="container panel panel-dark faq-wrap">
|
||||
<h2 class="center">{item().shortTitle} FAQs</h2>
|
||||
<div class="faq-list">
|
||||
<For each={item().faqs}>
|
||||
{(faq, idx) => (
|
||||
<article class={`faq-item ${openFaqIdx() === idx() ? 'open' : ''}`}>
|
||||
<button class="faq-q" type="button" onClick={() => setOpenFaqIdx((prev) => (prev === idx() ? -1 : idx()))}>
|
||||
<span>{faq.q}</span>
|
||||
<span class={`faq-q-icon ${openFaqIdx() === idx() ? 'open' : ''}`}>⌄</span>
|
||||
</button>
|
||||
<Show when={openFaqIdx() === idx()}>
|
||||
<p class="faq-a">{faq.a}</p>
|
||||
</Show>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="public-section lp-section">
|
||||
<div class="container panel panel-dark cta-panel">
|
||||
<div class="cta-copy">
|
||||
<p class="eyebrow">Start now</p>
|
||||
<h2>{item().finalCtaHeading}</h2>
|
||||
<p class="sub">{item().finalCtaSupport}</p>
|
||||
<div class="pro-detail-cta-points">
|
||||
<span>Single account</span>
|
||||
<span>Role visibility</span>
|
||||
<span>Trust approvals</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-actions cta-actions">
|
||||
<A class="lp-primary-btn pulse" href={item().finalPrimaryCta.href}>{item().finalPrimaryCta.label}</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href={item().finalSecondaryCta.href}>{item().finalSecondaryCta.label}</A>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
</Show>
|
||||
|
||||
<PublicFooter />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
395
src/data/help-center-seed.ts
Normal file
395
src/data/help-center-seed.ts
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
export type SeedHelpCategory = {
|
||||
id: string;
|
||||
key: string;
|
||||
title: string;
|
||||
};
|
||||
|
||||
export type SeedHelpArticle = {
|
||||
id: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
summary: string;
|
||||
categoryKey: string;
|
||||
category: string;
|
||||
role: 'ALL' | 'company' | 'jobSeeker' | 'professional' | 'customer' | 'platform';
|
||||
tags: string[];
|
||||
updatedAt: string;
|
||||
content: string;
|
||||
};
|
||||
|
||||
export const HELP_CENTER_SEED_CATEGORIES: SeedHelpCategory[] = [
|
||||
{ id: 'seed-cat-getting-started', key: 'getting-started', title: 'Getting Started' },
|
||||
{ id: 'seed-cat-account-login', key: 'account-login', title: 'Account & Login' },
|
||||
{ id: 'seed-cat-profile-verification', key: 'profile-verification', title: 'Profile & Verification' },
|
||||
{ id: 'seed-cat-platform-basics', key: 'platform-basics', title: 'Platform Basics' },
|
||||
{ id: 'seed-cat-jobs-applications', key: 'jobs-applications', title: 'Jobs & Applications' },
|
||||
{ id: 'seed-cat-leads-requests', key: 'leads-requests', title: 'Leads & Requests' },
|
||||
{ id: 'seed-cat-tracecoins-billing', key: 'tracecoins-billing', title: 'TraceCoins & Billing' },
|
||||
{ id: 'seed-cat-privacy-safety', key: 'privacy-safety', title: 'Privacy & Safety' },
|
||||
{ id: 'seed-cat-troubleshooting', key: 'troubleshooting', title: 'Troubleshooting' },
|
||||
];
|
||||
|
||||
const updatedAt = '2026-04-06T00:00:00.000Z';
|
||||
|
||||
export const HELP_CENTER_SEED_ARTICLES: SeedHelpArticle[] = [
|
||||
{
|
||||
id: 'seed-1',
|
||||
slug: 'create-account-3-steps',
|
||||
title: 'Create your Nxtgauge account in 3 steps',
|
||||
summary: 'Quick steps to sign up, verify, and get ready for your role journey.',
|
||||
categoryKey: 'getting-started',
|
||||
category: 'Getting Started',
|
||||
role: 'ALL',
|
||||
tags: ['account', 'signup', 'getting started'],
|
||||
updatedAt,
|
||||
content: 'Step 1: Sign up with your email or mobile number.\n\nStep 2: Verify OTP and complete basic account details.\n\nStep 3: Continue to role setup and complete your profile.',
|
||||
},
|
||||
{
|
||||
id: 'seed-2',
|
||||
slug: 'choose-role-after-signup',
|
||||
title: 'Choose your role after signup',
|
||||
summary: 'You can create one account first and activate the role path later.',
|
||||
categoryKey: 'getting-started',
|
||||
category: 'Getting Started',
|
||||
role: 'ALL',
|
||||
tags: ['role', 'signup'],
|
||||
updatedAt,
|
||||
content: 'Nxtgauge supports one account with role-based journeys.\n\nAfter signup, choose the role flow you need: company, professional, job seeker, or customer.',
|
||||
},
|
||||
{
|
||||
id: 'seed-3',
|
||||
slug: 'understand-account-statuses',
|
||||
title: 'Understand account statuses: Draft, Review, Approved',
|
||||
summary: 'Learn what each status means and what to do next.',
|
||||
categoryKey: 'getting-started',
|
||||
category: 'Getting Started',
|
||||
role: 'ALL',
|
||||
tags: ['status', 'approval'],
|
||||
updatedAt,
|
||||
content: 'Draft means incomplete.\n\nReview means your submission is being checked.\n\nApproved means your profile or listing is visible in discovery.',
|
||||
},
|
||||
{
|
||||
id: 'seed-4',
|
||||
slug: 'how-nxtgauge-platform-works',
|
||||
title: 'How the Nxtgauge platform works',
|
||||
summary: 'A trust-led submission, review, approval, and discovery workflow.',
|
||||
categoryKey: 'platform-basics',
|
||||
category: 'Platform Basics',
|
||||
role: 'platform',
|
||||
tags: ['workflow', 'trust'],
|
||||
updatedAt,
|
||||
content: 'Users submit profiles, requirements, or jobs.\n\nNxtgauge verifies submissions.\n\nApproved records become visible for discovery and matching.',
|
||||
},
|
||||
{
|
||||
id: 'seed-5',
|
||||
slug: 'one-account-multiple-journeys',
|
||||
title: 'One account, multiple journeys explained',
|
||||
summary: 'Use one account and activate the journey you need.',
|
||||
categoryKey: 'platform-basics',
|
||||
category: 'Platform Basics',
|
||||
role: 'platform',
|
||||
tags: ['account', 'roles'],
|
||||
updatedAt,
|
||||
content: 'You do not need separate accounts for each role.\n\nKeep each role profile complete for better matching quality.',
|
||||
},
|
||||
{
|
||||
id: 'seed-6',
|
||||
slug: 'review-approval-improve-trust',
|
||||
title: 'How review and approval improve trust',
|
||||
summary: 'Approval checkpoints reduce noise and increase confidence.',
|
||||
categoryKey: 'platform-basics',
|
||||
category: 'Platform Basics',
|
||||
role: 'platform',
|
||||
tags: ['review', 'approval', 'trust'],
|
||||
updatedAt,
|
||||
content: 'Review and approval reduce low-quality submissions.\n\nThis creates cleaner discovery and better first-contact confidence.',
|
||||
},
|
||||
{
|
||||
id: 'seed-7',
|
||||
slug: 'track-progress-without-confusion',
|
||||
title: 'How to track progress without confusion',
|
||||
summary: 'Use clear status labels and next actions from your dashboard.',
|
||||
categoryKey: 'platform-basics',
|
||||
category: 'Platform Basics',
|
||||
role: 'ALL',
|
||||
tags: ['tracking', 'status'],
|
||||
updatedAt,
|
||||
content: 'Check status labels daily.\n\nRespond quickly to changes.\n\nFollow the next action shown in your panel.',
|
||||
},
|
||||
{
|
||||
id: 'seed-8',
|
||||
slug: 'platform-terms-simple-words',
|
||||
title: 'Common platform terms in simple words',
|
||||
summary: 'A quick glossary for Draft, Review, Approved, Requirement, and Lead.',
|
||||
categoryKey: 'platform-basics',
|
||||
category: 'Platform Basics',
|
||||
role: 'ALL',
|
||||
tags: ['glossary', 'terms'],
|
||||
updatedAt,
|
||||
content: 'Draft: incomplete.\n\nReview: in verification.\n\nApproved: visible in platform.\n\nRequirement: customer need.\n\nLead: potential opportunity.',
|
||||
},
|
||||
{
|
||||
id: 'seed-9',
|
||||
slug: 'get-better-platform-visibility',
|
||||
title: 'How to get better platform visibility',
|
||||
summary: 'Practical profile improvements that increase discovery quality.',
|
||||
categoryKey: 'platform-basics',
|
||||
category: 'Platform Basics',
|
||||
role: 'ALL',
|
||||
tags: ['visibility', 'profile'],
|
||||
updatedAt,
|
||||
content: 'Complete profile fields, clarify scope, and keep proof updated.\n\nClear profiles usually perform better in discovery.',
|
||||
},
|
||||
{
|
||||
id: 'seed-10',
|
||||
slug: 'reset-password',
|
||||
title: 'How to reset your password',
|
||||
summary: 'Use the forgot password flow and verify securely with OTP.',
|
||||
categoryKey: 'account-login',
|
||||
category: 'Account & Login',
|
||||
role: 'ALL',
|
||||
tags: ['password', 'login'],
|
||||
updatedAt,
|
||||
content: 'Use Forgot Password on the login screen.\n\nVerify OTP and set a new secure password.',
|
||||
},
|
||||
{
|
||||
id: 'seed-11',
|
||||
slug: 'otp-failure-reasons',
|
||||
title: 'Why your login OTP might fail',
|
||||
summary: 'Common OTP failures and quick retry guidance.',
|
||||
categoryKey: 'account-login',
|
||||
category: 'Account & Login',
|
||||
role: 'ALL',
|
||||
tags: ['otp', 'login'],
|
||||
updatedAt,
|
||||
content: 'OTP can fail due to expiry, wrong input, or network delays.\n\nRequest a fresh OTP and retry.',
|
||||
},
|
||||
{
|
||||
id: 'seed-12',
|
||||
slug: 'update-email-phone',
|
||||
title: 'Update email or phone on your account',
|
||||
summary: 'How to request secure account contact updates.',
|
||||
categoryKey: 'account-login',
|
||||
category: 'Account & Login',
|
||||
role: 'ALL',
|
||||
tags: ['account', 'security'],
|
||||
updatedAt,
|
||||
content: 'Go to account settings and submit an update request.\n\nSome changes may require re-verification.',
|
||||
},
|
||||
{
|
||||
id: 'seed-13',
|
||||
slug: 'high-conversion-profile',
|
||||
title: 'How to complete a high-conversion profile',
|
||||
summary: 'Role clarity, scope, portfolio proof, and pricing structure tips.',
|
||||
categoryKey: 'profile-verification',
|
||||
category: 'Profile & Verification',
|
||||
role: 'professional',
|
||||
tags: ['profile', 'conversion'],
|
||||
updatedAt,
|
||||
content: 'Add clear role scope, location, portfolio proof, and service details.\n\nClear profiles get better-fit responses.',
|
||||
},
|
||||
{
|
||||
id: 'seed-14',
|
||||
slug: 'verification-checklist-before-submit',
|
||||
title: 'Verification checklist before submission',
|
||||
summary: 'Use this checklist to reduce correction loops.',
|
||||
categoryKey: 'profile-verification',
|
||||
category: 'Profile & Verification',
|
||||
role: 'ALL',
|
||||
tags: ['verification', 'checklist'],
|
||||
updatedAt,
|
||||
content: 'Check identity fields, category fit, proof quality, and profile completeness before submission.',
|
||||
},
|
||||
{
|
||||
id: 'seed-15',
|
||||
slug: 'verification-timeline-24-48-hours',
|
||||
title: 'Expected verification timeline (24-48 hours)',
|
||||
summary: 'What is normal and what can delay review outcomes.',
|
||||
categoryKey: 'profile-verification',
|
||||
category: 'Profile & Verification',
|
||||
role: 'ALL',
|
||||
tags: ['verification', 'timeline'],
|
||||
updatedAt,
|
||||
content: 'Most profile reviews complete within 24-48 hours.\n\nComplex or incomplete submissions can take longer.',
|
||||
},
|
||||
{
|
||||
id: 'seed-16',
|
||||
slug: 'verification-sent-back-correction',
|
||||
title: 'Why verification was sent back for correction',
|
||||
summary: 'Top reasons for correction requests and how to fix quickly.',
|
||||
categoryKey: 'profile-verification',
|
||||
category: 'Profile & Verification',
|
||||
role: 'ALL',
|
||||
tags: ['verification', 'correction'],
|
||||
updatedAt,
|
||||
content: 'Corrections happen when data is missing, unclear, mismatched, or unsupported.\n\nUpdate details and resubmit.',
|
||||
},
|
||||
{
|
||||
id: 'seed-17',
|
||||
slug: 'companies-post-jobs-correctly',
|
||||
title: 'How companies can post jobs correctly',
|
||||
summary: 'Improve candidate quality with clear role details.',
|
||||
categoryKey: 'jobs-applications',
|
||||
category: 'Jobs & Applications',
|
||||
role: 'company',
|
||||
tags: ['jobs', 'company'],
|
||||
updatedAt,
|
||||
content: 'Use clear job titles, responsibilities, compensation, location, and timeline.\n\nGood clarity improves candidate relevance.',
|
||||
},
|
||||
{
|
||||
id: 'seed-18',
|
||||
slug: 'track-application-status',
|
||||
title: 'How job seekers can track application status',
|
||||
summary: 'Understand submitted, viewed, shortlisted, and closed states.',
|
||||
categoryKey: 'jobs-applications',
|
||||
category: 'Jobs & Applications',
|
||||
role: 'jobSeeker',
|
||||
tags: ['application', 'job seeker'],
|
||||
updatedAt,
|
||||
content: 'Check your applications panel for status changes.\n\nKeep your profile updated to support faster responses.',
|
||||
},
|
||||
{
|
||||
id: 'seed-19',
|
||||
slug: 'improve-application-quality',
|
||||
title: 'How to improve job application quality',
|
||||
summary: 'Simple ways to increase first-pass quality.',
|
||||
categoryKey: 'jobs-applications',
|
||||
category: 'Jobs & Applications',
|
||||
role: 'jobSeeker',
|
||||
tags: ['application', 'quality'],
|
||||
updatedAt,
|
||||
content: 'Tailor profile details to each role and add relevant work proof where possible.',
|
||||
},
|
||||
{
|
||||
id: 'seed-20',
|
||||
slug: 'handle-duplicate-irrelevant-leads',
|
||||
title: 'Handling duplicate or irrelevant leads',
|
||||
summary: 'Reduce noise with better targeting and filters.',
|
||||
categoryKey: 'leads-requests',
|
||||
category: 'Leads & Requests',
|
||||
role: 'professional',
|
||||
tags: ['leads', 'filters'],
|
||||
updatedAt,
|
||||
content: 'Use lead filters and quick decline flows for low-fit requests.\n\nImprove profile targeting to reduce irrelevant leads.',
|
||||
},
|
||||
{
|
||||
id: 'seed-21',
|
||||
slug: 'best-response-window-lead-conversion',
|
||||
title: 'Best response window for higher lead conversion',
|
||||
summary: 'Speed and clarity can improve first-contact outcomes.',
|
||||
categoryKey: 'leads-requests',
|
||||
category: 'Leads & Requests',
|
||||
role: 'professional',
|
||||
tags: ['conversion', 'response'],
|
||||
updatedAt,
|
||||
content: 'Respond early with clear scope and timeline.\n\nStructured replies usually perform better.',
|
||||
},
|
||||
{
|
||||
id: 'seed-22',
|
||||
slug: 'organize-customer-requests',
|
||||
title: 'How to organize incoming customer requests',
|
||||
summary: 'Prioritization methods for faster handling.',
|
||||
categoryKey: 'leads-requests',
|
||||
category: 'Leads & Requests',
|
||||
role: 'professional',
|
||||
tags: ['requests', 'workflow'],
|
||||
updatedAt,
|
||||
content: 'Tag requests by urgency, scope, and budget.\n\nPrioritize high-fit requests first.',
|
||||
},
|
||||
{
|
||||
id: 'seed-23',
|
||||
slug: 'what-are-tracecoins',
|
||||
title: 'What are TraceCoins and where they are used',
|
||||
summary: 'TraceCoins are platform credits used in selected flows.',
|
||||
categoryKey: 'tracecoins-billing',
|
||||
category: 'TraceCoins & Billing',
|
||||
role: 'ALL',
|
||||
tags: ['tracecoins', 'billing'],
|
||||
updatedAt,
|
||||
content: 'TraceCoins are credits for selected premium interactions and utilities inside the platform.',
|
||||
},
|
||||
{
|
||||
id: 'seed-24',
|
||||
slug: 'view-invoices-payment-history',
|
||||
title: 'How to view invoices and payment history',
|
||||
summary: 'Where to find transaction records and billing references.',
|
||||
categoryKey: 'tracecoins-billing',
|
||||
category: 'TraceCoins & Billing',
|
||||
role: 'ALL',
|
||||
tags: ['invoice', 'payments'],
|
||||
updatedAt,
|
||||
content: 'Open billing settings to view purchase records and invoice history.',
|
||||
},
|
||||
{
|
||||
id: 'seed-25',
|
||||
slug: 'refund-failed-payment-guidance',
|
||||
title: 'Refund and failed payment guidance',
|
||||
summary: 'What to do first when transactions fail or remain pending.',
|
||||
categoryKey: 'tracecoins-billing',
|
||||
category: 'TraceCoins & Billing',
|
||||
role: 'ALL',
|
||||
tags: ['refund', 'payment'],
|
||||
updatedAt,
|
||||
content: 'Check payment status first, then raise support with transaction reference if needed.',
|
||||
},
|
||||
{
|
||||
id: 'seed-26',
|
||||
slug: 'report-suspicious-activity',
|
||||
title: 'How to report suspicious activity',
|
||||
summary: 'Raise reports quickly and include useful evidence.',
|
||||
categoryKey: 'privacy-safety',
|
||||
category: 'Privacy & Safety',
|
||||
role: 'ALL',
|
||||
tags: ['safety', 'report'],
|
||||
updatedAt,
|
||||
content: 'Use report actions on profiles or listings and include evidence to help faster review.',
|
||||
},
|
||||
{
|
||||
id: 'seed-27',
|
||||
slug: 'manage-privacy-settings',
|
||||
title: 'Managing privacy settings for your account',
|
||||
summary: 'Control profile visibility and communication preferences.',
|
||||
categoryKey: 'privacy-safety',
|
||||
category: 'Privacy & Safety',
|
||||
role: 'ALL',
|
||||
tags: ['privacy', 'settings'],
|
||||
updatedAt,
|
||||
content: 'Adjust profile visibility and notification preferences from account settings.',
|
||||
},
|
||||
{
|
||||
id: 'seed-28',
|
||||
slug: 'account-safety-best-practices',
|
||||
title: 'Account safety best practices',
|
||||
summary: 'Simple security habits to protect your account.',
|
||||
categoryKey: 'privacy-safety',
|
||||
category: 'Privacy & Safety',
|
||||
role: 'ALL',
|
||||
tags: ['security', 'account'],
|
||||
updatedAt,
|
||||
content: 'Use strong passwords, rotate credentials, and never share OTP codes.',
|
||||
},
|
||||
{
|
||||
id: 'seed-29',
|
||||
slug: 'fix-profile-image-upload-issues',
|
||||
title: 'Fix profile image or upload issues',
|
||||
summary: 'Common upload fixes and file readiness checks.',
|
||||
categoryKey: 'troubleshooting',
|
||||
category: 'Troubleshooting',
|
||||
role: 'ALL',
|
||||
tags: ['upload', 'profile image'],
|
||||
updatedAt,
|
||||
content: 'Try supported formats, smaller file sizes, and stable network before retrying upload.',
|
||||
},
|
||||
{
|
||||
id: 'seed-30',
|
||||
slug: 'dashboard-data-not-refreshing',
|
||||
title: 'What to do if dashboard data does not refresh',
|
||||
summary: 'Quick checks for stale status or delayed updates.',
|
||||
categoryKey: 'troubleshooting',
|
||||
category: 'Troubleshooting',
|
||||
role: 'ALL',
|
||||
tags: ['dashboard', 'refresh'],
|
||||
updatedAt,
|
||||
content: 'Refresh session, confirm active role context, and retry.\n\nIf issue persists, contact support with exact status details.',
|
||||
},
|
||||
];
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { HELP_CENTER_SEED_ARTICLES, HELP_CENTER_SEED_CATEGORIES } from '~/data/help-center-seed';
|
||||
|
||||
export type HelpArticle = {
|
||||
id: string;
|
||||
slug: string;
|
||||
|
|
@ -31,39 +33,78 @@ export async function fetchHelpCenterArticles(input: {
|
|||
|
||||
try {
|
||||
const res = await fetch(`/api/kb/articles?${params.toString()}`);
|
||||
if (!res.ok) return [];
|
||||
if (!res.ok) return filterArticles(HELP_CENTER_SEED_ARTICLES as HelpArticle[], input);
|
||||
const data = await res.json();
|
||||
const raw: any[] = Array.isArray(data) ? data : (data.articles ?? []);
|
||||
return raw.map(normalizeArticle);
|
||||
let items = raw.map(normalizeArticle);
|
||||
|
||||
// Fallback: when backend search returns sparse/empty data, apply local filtering
|
||||
// so users can still find articles by simple keywords.
|
||||
if (input.q && items.length === 0) {
|
||||
const allRes = await fetch('/api/kb/articles');
|
||||
if (allRes.ok) {
|
||||
const allData = await allRes.json();
|
||||
const allRaw: any[] = Array.isArray(allData) ? allData : (allData.articles ?? []);
|
||||
items = allRaw.map(normalizeArticle);
|
||||
}
|
||||
}
|
||||
|
||||
if (items.length === 0) {
|
||||
items = HELP_CENTER_SEED_ARTICLES as HelpArticle[];
|
||||
}
|
||||
|
||||
return filterArticles(items, input);
|
||||
} catch {
|
||||
return [];
|
||||
return filterArticles(HELP_CENTER_SEED_ARTICLES as HelpArticle[], input);
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchHelpCenterCategories(): Promise<HelpCategory[]> {
|
||||
try {
|
||||
const res = await fetch('/api/kb/categories');
|
||||
if (!res.ok) return [];
|
||||
if (!res.ok) return HELP_CENTER_SEED_CATEGORIES;
|
||||
const data = await res.json();
|
||||
const raw: any[] = Array.isArray(data) ? data : (data.categories ?? []);
|
||||
return raw.map((c) => ({
|
||||
const mapped = raw.map((c) => ({
|
||||
id: c.id,
|
||||
key: c.slug,
|
||||
title: c.name,
|
||||
key: c.slug ?? c.key,
|
||||
title: c.name ?? c.title,
|
||||
}));
|
||||
return mapped.length > 0 ? mapped : HELP_CENTER_SEED_CATEGORIES;
|
||||
} catch {
|
||||
return [];
|
||||
return HELP_CENTER_SEED_CATEGORIES;
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchArticleBySlug(slug: string): Promise<HelpArticle | null> {
|
||||
try {
|
||||
const res = await fetch(`/api/kb/articles/${slug}`);
|
||||
if (!res.ok) return null;
|
||||
if (!res.ok) return (HELP_CENTER_SEED_ARTICLES as HelpArticle[]).find((a) => a.slug === slug) ?? null;
|
||||
const data = await res.json();
|
||||
return normalizeArticle(data);
|
||||
const normalized = normalizeArticle(data);
|
||||
if (!normalized.slug) {
|
||||
return (HELP_CENTER_SEED_ARTICLES as HelpArticle[]).find((a) => a.slug === slug) ?? null;
|
||||
}
|
||||
return normalized;
|
||||
} catch {
|
||||
return null;
|
||||
return (HELP_CENTER_SEED_ARTICLES as HelpArticle[]).find((a) => a.slug === slug) ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchRelatedArticles(input: {
|
||||
article: HelpArticle;
|
||||
limit?: number;
|
||||
}): Promise<HelpArticle[]> {
|
||||
try {
|
||||
const res = await fetch('/api/kb/articles');
|
||||
if (!res.ok) return pickRelated(HELP_CENTER_SEED_ARTICLES as HelpArticle[], input.article, input.limit ?? 4);
|
||||
const data = await res.json();
|
||||
const raw: any[] = Array.isArray(data) ? data : (data.articles ?? []);
|
||||
const all = raw.map(normalizeArticle);
|
||||
if (all.length === 0) return pickRelated(HELP_CENTER_SEED_ARTICLES as HelpArticle[], input.article, input.limit ?? 4);
|
||||
return pickRelated(all, input.article, input.limit ?? 4);
|
||||
} catch {
|
||||
return pickRelated(HELP_CENTER_SEED_ARTICLES as HelpArticle[], input.article, input.limit ?? 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,3 +139,40 @@ export function listHelpCenterCategories(): HelpCategory[] {
|
|||
export function getArticleBySlug(_slug: string): HelpArticle | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
function articleMatchesQuery(article: HelpArticle, needle: string): boolean {
|
||||
const haystack = [article.title, article.summary, article.content, article.category, article.categoryKey, article.tags.join(' ')].join(' ').toLowerCase();
|
||||
return haystack.includes(needle);
|
||||
}
|
||||
|
||||
function filterArticles(items: HelpArticle[], input: { role?: string; categoryKey?: string; q?: string }): HelpArticle[] {
|
||||
let filtered = items;
|
||||
|
||||
if (input.role && input.role !== 'ALL') {
|
||||
const roleNeedle = input.role.toLowerCase();
|
||||
filtered = filtered.filter((a) => a.role === 'ALL' || String(a.role).toLowerCase() === roleNeedle);
|
||||
}
|
||||
|
||||
if (input.categoryKey) {
|
||||
const needle = input.categoryKey.toLowerCase();
|
||||
filtered = filtered.filter((a) => [a.categoryKey, a.category].some((v) => (v || '').toLowerCase().includes(needle)));
|
||||
}
|
||||
|
||||
if (input.q) {
|
||||
const needle = input.q.toLowerCase();
|
||||
filtered = filtered.filter((a) => articleMatchesQuery(a, needle));
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
function pickRelated(allItems: HelpArticle[], current: HelpArticle, limit: number): HelpArticle[] {
|
||||
const all = allItems.filter((a) => a.slug !== current.slug);
|
||||
const sameCategory = all.filter((a) => {
|
||||
const left = `${a.categoryKey}|${a.category}`.toLowerCase();
|
||||
const right = `${current.categoryKey}|${current.category}`.toLowerCase();
|
||||
return left && right && left === right;
|
||||
});
|
||||
const fallback = all.filter((a) => !sameCategory.some((x) => x.slug === a.slug));
|
||||
return [...sameCategory, ...fallback].slice(0, limit);
|
||||
}
|
||||
|
|
|
|||
187
src/lib/professionals.ts
Normal file
187
src/lib/professionals.ts
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
export type ProfessionalCategory = 'tech' | 'creative' | 'education' | 'wellness' | 'events' | 'marketing';
|
||||
|
||||
export type ProfessionalPageContent = {
|
||||
slug: string;
|
||||
roleKey: string;
|
||||
title: string;
|
||||
shortTitle: string;
|
||||
heroTitle: string;
|
||||
heroDescription: string;
|
||||
image: string;
|
||||
category: ProfessionalCategory;
|
||||
benefits: string[];
|
||||
offerHighlights: string[];
|
||||
faqs: Array<{ q: string; a: string }>;
|
||||
};
|
||||
|
||||
export const professionalPages: ProfessionalPageContent[] = [
|
||||
{
|
||||
slug: 'developer',
|
||||
roleKey: 'DEVELOPER',
|
||||
title: 'Developer Professionals',
|
||||
shortTitle: 'Developer',
|
||||
heroTitle: 'Get verified development opportunities with clear project scope.',
|
||||
heroDescription: 'Join Nxtgauge as a Developer and connect with customers and companies through a trust-first workflow.',
|
||||
image: 'https://images.unsplash.com/photo-1498050108023-c5249f4df085?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'tech',
|
||||
benefits: ['Verified client requirements', 'Structured project details before outreach', 'Clear status tracking for requests and approvals'],
|
||||
offerHighlights: ['Build your trusted developer profile', 'Respond to relevant, role-matched opportunities', 'Grow with less marketplace noise'],
|
||||
faqs: [
|
||||
{ q: 'Who should join this page?', a: 'Developers looking for verified client demand and structured project discovery.' },
|
||||
{ q: 'How do opportunities stay high quality?', a: 'Requirements and profiles flow through review checkpoints before they become visible.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'photographer',
|
||||
roleKey: 'PHOTOGRAPHER',
|
||||
title: 'Photographer Professionals',
|
||||
shortTitle: 'Photographer',
|
||||
heroTitle: 'Show your portfolio to verified customers and event-focused demand.',
|
||||
heroDescription: 'Join as a Photographer and receive opportunities where trust and profile quality matter.',
|
||||
image: 'https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'creative',
|
||||
benefits: ['Verified requirement flow', 'Profile-led visibility', 'Cleaner discovery for event and brand shoots'],
|
||||
offerHighlights: ['Build a trustworthy public profile', 'Get discovered by relevant customer needs', 'Track every response in one workflow'],
|
||||
faqs: [
|
||||
{ q: 'Can I highlight specialization?', a: 'Yes. Your profile setup helps present service type and strengths clearly.' },
|
||||
{ q: 'Why is verification useful for photographers?', a: 'It reduces spam and improves confidence for both professionals and customers.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'makeup-artist',
|
||||
roleKey: 'MAKEUP_ARTIST',
|
||||
title: 'Makeup Artist Professionals',
|
||||
shortTitle: 'Makeup Artist',
|
||||
heroTitle: 'Grow your makeup services with trusted profile-based discovery.',
|
||||
heroDescription: 'Join Nxtgauge as a Makeup Artist and connect with verified requirements from customers and event planners.',
|
||||
image: 'https://images.unsplash.com/photo-1522335789203-aabd1fc54bc9?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'creative',
|
||||
benefits: ['Verified service requests', 'Cleaner lead quality', 'Role-relevant visibility for styling work'],
|
||||
offerHighlights: ['Create a strong professional profile', 'Respond to approved demand', 'Track status without confusion'],
|
||||
faqs: [
|
||||
{ q: 'Is this for freelance artists only?', a: 'It works for freelance and studio-aligned professionals.' },
|
||||
{ q: 'What is the biggest advantage here?', a: 'Trust-led discovery reduces low-intent requests and improves match quality.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'tutor',
|
||||
roleKey: 'TUTOR',
|
||||
title: 'Tutor Professionals',
|
||||
shortTitle: 'Tutor',
|
||||
heroTitle: 'Reach serious learners through a trusted tutoring discovery flow.',
|
||||
heroDescription: 'Join as a Tutor to receive verified educational requirements and present your profile with confidence.',
|
||||
image: 'https://images.unsplash.com/photo-1497633762265-9d179a990aa6?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'education',
|
||||
benefits: ['Verified learner requirements', 'Structured profile presentation', 'Focused subject-based discovery'],
|
||||
offerHighlights: ['Show your strengths and teaching profile', 'Get matched to relevant demand', 'Manage responses with transparent status'],
|
||||
faqs: [
|
||||
{ q: 'Can tutors from different subjects join?', a: 'Yes. The role is designed for broad education categories and specialization.' },
|
||||
{ q: 'How does trust help tutoring?', a: 'It improves confidence and reduces low-quality demand signals.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'video-editor',
|
||||
roleKey: 'VIDEO_EDITOR',
|
||||
title: 'Video Editor Professionals',
|
||||
shortTitle: 'Video Editor',
|
||||
heroTitle: 'Find better-fit editing opportunities through verified demand.',
|
||||
heroDescription: 'Join as a Video Editor and connect with customers and companies through a review-based trust model.',
|
||||
image: 'https://images.unsplash.com/photo-1574717024653-61fd2cf4d44d?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'creative',
|
||||
benefits: ['Verified project requirements', 'Better fit between role and demand', 'Clear, trackable opportunity states'],
|
||||
offerHighlights: ['Build a strong editing profile', 'Respond to trusted opportunities', 'Work with less marketplace noise'],
|
||||
faqs: [
|
||||
{ q: 'Does this support freelance editors?', a: 'Yes. Freelancers can join and grow through verified opportunity discovery.' },
|
||||
{ q: 'Why not a normal listing marketplace?', a: 'Nxtgauge emphasizes trust checks before visibility for better quality interactions.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'graphic-designer',
|
||||
roleKey: 'GRAPHIC_DESIGNER',
|
||||
title: 'Graphic Designer Professionals',
|
||||
shortTitle: 'Graphic Designer',
|
||||
heroTitle: 'Grow design demand through trust-first profile visibility.',
|
||||
heroDescription: 'Join as a Graphic Designer to connect with verified requirements and role-relevant opportunities.',
|
||||
image: 'https://images.unsplash.com/photo-1558655146-d09347e92766?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'creative',
|
||||
benefits: ['Verified design requests', 'Structured profile and credibility flow', 'Cleaner matching by role and requirement'],
|
||||
offerHighlights: ['Show your design strengths clearly', 'Respond to approved opportunities', 'Track engagement in one place'],
|
||||
faqs: [
|
||||
{ q: 'Can brand and social designers both use this?', a: 'Yes. The role supports multiple design demand contexts.' },
|
||||
{ q: 'What makes this trustworthy?', a: 'Approval and review checkpoints help reduce fake or low-quality submissions.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'social-media-manager',
|
||||
roleKey: 'SOCIAL_MEDIA_MANAGER',
|
||||
title: 'Social Media Manager Professionals',
|
||||
shortTitle: 'Social Media Manager',
|
||||
heroTitle: 'Access verified social growth opportunities with clearer demand signals.',
|
||||
heroDescription: 'Join as a Social Media Manager and grow with trusted customer and company requirements.',
|
||||
image: 'https://images.unsplash.com/photo-1611162618071-b39a2ec055fb?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'marketing',
|
||||
benefits: ['Verified campaign requirements', 'Role-specific discovery experience', 'Transparent status flow for responses'],
|
||||
offerHighlights: ['Build a profile clients can trust', 'Respond to relevant campaign demand', 'Manage opportunity updates with clarity'],
|
||||
faqs: [
|
||||
{ q: 'Is this useful for independent consultants?', a: 'Yes. It supports independent social media professionals and teams.' },
|
||||
{ q: 'How is demand quality maintained?', a: 'Review-oriented workflow helps surface more reliable opportunities.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'fitness-trainer',
|
||||
roleKey: 'FITNESS_TRAINER',
|
||||
title: 'Fitness Trainer Professionals',
|
||||
shortTitle: 'Fitness Trainer',
|
||||
heroTitle: 'Connect with verified fitness demand and build trust quickly.',
|
||||
heroDescription: 'Join as a Fitness Trainer and grow through profile-led visibility in a trust-first marketplace.',
|
||||
image: 'https://images.unsplash.com/photo-1517836357463-d25dfeac3438?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'wellness',
|
||||
benefits: ['Verified customer requirements', 'Cleaner demand discovery', 'Better trust signals for first-time clients'],
|
||||
offerHighlights: ['Create a strong trainer profile', 'Engage with trusted requirement flow', 'Track request movement clearly'],
|
||||
faqs: [
|
||||
{ q: 'Is this only for gym trainers?', a: 'No. It supports trainers across formats and specializations.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'catering-services',
|
||||
roleKey: 'CATERING_SERVICES',
|
||||
title: 'Catering Service Professionals',
|
||||
shortTitle: 'Catering Services',
|
||||
heroTitle: 'Get discovered for events through verified requirement workflows.',
|
||||
heroDescription: 'Join as a Catering Service professional and connect with trusted event demand.',
|
||||
image: 'https://images.unsplash.com/photo-1555244162-803834f70033?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'events',
|
||||
benefits: ['Verified event requirements', 'Profile-first trust visibility', 'Better opportunity clarity before engagement'],
|
||||
offerHighlights: ['Present your service profile with confidence', 'Respond to approved requirements', 'Track outcomes in one flow'],
|
||||
faqs: [
|
||||
{ q: 'Can small catering teams join?', a: 'Yes. Both individual and team-based providers can join.' },
|
||||
{ q: 'What is the key benefit?', a: 'Higher confidence in demand quality through trusted workflows.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'ugc-content-creator',
|
||||
roleKey: 'UGC_CONTENT_CREATOR',
|
||||
title: 'UGC Content Creator Professionals',
|
||||
shortTitle: 'UGC Content Creator',
|
||||
heroTitle: 'Find trusted brand collaboration demand with verified workflows.',
|
||||
heroDescription: 'Join as a UGC Content Creator and grow with role-matched, quality-controlled opportunities.',
|
||||
image: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?q=80&w=1200&auto=format&fit=crop',
|
||||
category: 'marketing',
|
||||
benefits: ['Verified campaign demand', 'Better matching for creator roles', 'Clear status visibility from request to response'],
|
||||
offerHighlights: ['Build a trusted creator profile', 'Respond to approved opportunities', 'Scale with less discovery noise'],
|
||||
faqs: [
|
||||
{ q: 'Is this focused on campaign-style work?', a: 'Yes. It is optimized for creator-brand collaboration demand.' },
|
||||
{ q: 'How does Nxtgauge help creators?', a: 'By emphasizing trust and verification before visibility and response cycles.' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export function getProfessionalBySlug(slug: string): ProfessionalPageContent | undefined {
|
||||
return professionalPages.find((item) => item.slug === slug);
|
||||
}
|
||||
|
||||
export function professionalSignupHref(roleKey: string): string {
|
||||
return `/signup?intent=professional&role=${encodeURIComponent(roleKey)}`;
|
||||
}
|
||||
|
||||
761
src/lib/role-landings.ts
Normal file
761
src/lib/role-landings.ts
Normal file
|
|
@ -0,0 +1,761 @@
|
|||
export type RoleLandingAudience = 'professional' | 'company' | 'customer' | 'job_seeker';
|
||||
|
||||
export type RoleLandingContent = {
|
||||
slug: string;
|
||||
roleKey: string;
|
||||
audience: RoleLandingAudience;
|
||||
shortTitle: string;
|
||||
heroEyebrow: string;
|
||||
heroTitle: string;
|
||||
heroDescription: string;
|
||||
heroImage: string;
|
||||
primaryCta: { label: string; href: string };
|
||||
secondaryCta: { label: string; href: string };
|
||||
whatYouGetTitle: string;
|
||||
whatYouGetSubtitle: string;
|
||||
whatYouGetCards: string[];
|
||||
typicalLeftTitle: string;
|
||||
typicalLeftItems: string[];
|
||||
typicalRightTitle: string;
|
||||
typicalRightItems: string[];
|
||||
howItWorksTitle: string;
|
||||
howItWorksSteps: Array<{ title: string; description: string }>;
|
||||
whyChooseTitle: string;
|
||||
whyChooseCards: string[];
|
||||
faqs: Array<{ q: string; a: string }>;
|
||||
finalCtaHeading: string;
|
||||
finalCtaSupport: string;
|
||||
finalPrimaryCta: { label: string; href: string };
|
||||
finalSecondaryCta: { label: string; href: string };
|
||||
};
|
||||
|
||||
export const roleTrustChips = [
|
||||
'24-48h review',
|
||||
'Role visibility',
|
||||
'Trust approvals',
|
||||
'Status tracking',
|
||||
] as const;
|
||||
|
||||
export const roleValueProps = [
|
||||
{
|
||||
title: 'Profile Review with Real Checks',
|
||||
body: 'Most profile reviews complete in 24-48 hours with clear approval outcomes.',
|
||||
},
|
||||
{
|
||||
title: 'Approved-First Visibility',
|
||||
body: 'Profiles, opportunities, or requirements move through trust checkpoints before discovery.',
|
||||
},
|
||||
{
|
||||
title: 'Clear Status Tracking',
|
||||
body: 'Track progress with less confusion and fewer dead ends.',
|
||||
},
|
||||
] as const;
|
||||
|
||||
export const roleChecklist = [
|
||||
'Complete your role profile with service scope, location, and clear details',
|
||||
'Add proof of work or supporting profile strength',
|
||||
'Include package, pricing, or service structure where relevant',
|
||||
'Submit for verification',
|
||||
'Monitor status updates',
|
||||
'Respond quickly to approved opportunities',
|
||||
] as const;
|
||||
|
||||
export const roleOutcomes = [
|
||||
'Trusted profile-led discovery',
|
||||
'Better first-contact trust',
|
||||
'Clearer request or opportunity tracking',
|
||||
'More structured workflow visibility',
|
||||
'Less confusion across stages',
|
||||
'Stronger service or role presentation',
|
||||
] as const;
|
||||
|
||||
const bySlug: Record<string, RoleLandingContent> = {
|
||||
company: {
|
||||
slug: 'company',
|
||||
roleKey: 'COMPANY',
|
||||
audience: 'company',
|
||||
shortTitle: 'Company',
|
||||
heroEyebrow: 'Company on Nxtgauge',
|
||||
heroTitle: 'Post verified jobs and hire faster through a trust-first workflow',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Company and publish job openings through a clearer, approval-led hiring journey. Build employer trust, present roles professionally, and attract better-fit applicants with less noise.',
|
||||
heroImage: '/images/roles/company.jpg',
|
||||
primaryCta: { label: 'Start as Company', href: '/signup?intent=company' },
|
||||
secondaryCta: { label: 'View Open Role Paths', href: '/roles/job-seeker' },
|
||||
whatYouGetTitle: 'What you get as a Company on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Verified job publishing - Create openings that move through trust and approval checkpoints before broad visibility.',
|
||||
'Stronger employer presentation - Show your company profile, role context, and hiring intent more clearly.',
|
||||
'Cleaner applicant flow - Reduce random applications and focus on more relevant candidate interest.',
|
||||
'Status clarity - Track review, approval, and response stages with less confusion.',
|
||||
'Better trust signals - Give applicants more confidence in the legitimacy of your openings.',
|
||||
'Structured hiring setup - Present role type, compensation, expectations, and hiring process in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical hiring needs from companies',
|
||||
typicalLeftItems: ['Full-time hiring', 'Part-time hiring', 'Internship openings', 'Contract hiring', 'Project-based roles', 'Urgent replacement hiring'],
|
||||
typicalRightTitle: 'What candidates usually expect',
|
||||
typicalRightItems: ['Clear role title and responsibilities', 'Company credibility', 'Salary or compensation clarity', 'Work mode and location', 'Application timeline', 'Response visibility'],
|
||||
howItWorksTitle: 'How joining as a Company works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your employer journey.' },
|
||||
{ title: 'Complete your company profile', description: 'Add company details, hiring context, and business information.' },
|
||||
{ title: 'Post a job and submit for review', description: 'Openings move through approval before broader visibility.' },
|
||||
{ title: 'Track applicants and responses', description: 'Monitor status updates and manage hiring flow more clearly.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Companies choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified job environment - Helps your openings stand out from low-trust public listings.',
|
||||
'Better-fit applicants - Supports clearer discovery for job seekers who match your needs.',
|
||||
'More structured hiring flow - Gives your team a cleaner process from posting to response tracking.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Can I post internships too?', a: 'Yes. Companies can present full-time, part-time, internship, and other role formats.' },
|
||||
{ q: 'Why is approval important for company listings?', a: 'It improves trust for applicants and helps reduce low-quality or misleading posts.' },
|
||||
{ q: 'Do I need a separate account for each role?', a: 'No. Nxtgauge supports one account with different role journeys.' },
|
||||
{ q: 'What should I include in a job post?', a: 'Add role title, location, work type, responsibilities, candidate expectations, and hiring details.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile or job-related approvals are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Company profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Start as Company', href: '/signup?intent=company' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
customer: {
|
||||
slug: 'customer',
|
||||
roleKey: 'CUSTOMER',
|
||||
audience: 'customer',
|
||||
shortTitle: 'Customer',
|
||||
heroEyebrow: 'Customer on Nxtgauge',
|
||||
heroTitle: 'Post your requirement and discover verified professionals with less noise',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Customer and find professionals through a trust-first requirement flow. Share what you need, move through quality checks, and get clearer responses from better-presented profiles.',
|
||||
heroImage: '/images/roles/service_seeker.jpg',
|
||||
primaryCta: { label: 'Start as Customer', href: '/signup?intent=customer' },
|
||||
secondaryCta: { label: 'Hire a Professional', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Customer on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Verified requirement flow - Requirements move through review before broader discovery.',
|
||||
'Better professional trust - See specialists with stronger profile and approval signals.',
|
||||
'Cleaner discovery - Reduce random replies and focus on more relevant professionals.',
|
||||
'Status visibility - Track how your request progresses and who responds.',
|
||||
'Better first-contact confidence - Make decisions with clearer profile context.',
|
||||
'Structured requirement posting - Present budget, timing, location, and scope in one flow.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical customer needs on Nxtgauge',
|
||||
typicalLeftItems: ['Event-based services', 'Creative service hiring', 'Coaching and tutoring support', 'Home or lifestyle service needs', 'Business support requirements', 'Urgent specialist requests'],
|
||||
typicalRightTitle: 'What customers usually want to compare',
|
||||
typicalRightItems: ['Service fit', 'Availability', 'Location', 'Pricing or package structure', 'Trust signals', 'Communication clarity'],
|
||||
howItWorksTitle: 'How joining as a Customer works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and begin your customer path.' },
|
||||
{ title: 'Share your requirement', description: 'Add scope, budget, timing, and key details.' },
|
||||
{ title: 'Requirement review', description: 'Quality checks help improve trust before full discovery.' },
|
||||
{ title: 'Track responses', description: 'Monitor replies and request status more clearly.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Customers choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified specialist discovery - See professionals through a more trust-led system.',
|
||||
'Cleaner response flow - Reduce confusion across replies and request stages.',
|
||||
'Better fit before contact - Compare stronger profiles before moving ahead.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Can I post any type of requirement?', a: 'You can post requirements that fit the supported categories and role flows on the platform.' },
|
||||
{ q: 'Why does review matter for customers?', a: 'It helps maintain trust, reduce fake activity, and improve discovery quality.' },
|
||||
{ q: 'Do I need to select one professional immediately?', a: 'No. You can review profiles and move based on fit and responses.' },
|
||||
{ q: 'What should I include in my requirement?', a: 'Add your goal, timing, location, budget, and anything important for matching.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most review or approval steps are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Customer profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Start as Customer', href: '/signup?intent=customer' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'job-seeker': {
|
||||
slug: 'job-seeker',
|
||||
roleKey: 'JOB_SEEKER',
|
||||
audience: 'job_seeker',
|
||||
shortTitle: 'Job Seeker',
|
||||
heroEyebrow: 'Job Seeker on Nxtgauge',
|
||||
heroTitle: 'Apply to approved opportunities with a stronger profile and clearer status flow',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Job Seeker and move through a more structured job search experience. Build a trusted profile, apply to approved openings, and track your progress with better visibility.',
|
||||
heroImage: '/images/roles/job_seeker.jpg',
|
||||
primaryCta: { label: 'Start as Job Seeker', href: '/signup?intent=job_seeker' },
|
||||
secondaryCta: { label: 'View Open Opportunities', href: '/roles/company' },
|
||||
whatYouGetTitle: 'What you get as a Job Seeker on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Approved opportunity access - Browse job openings that sit inside a trust-first workflow.',
|
||||
'Stronger candidate profile - Present experience, skills, and role interests more clearly.',
|
||||
'Less application noise - Focus on verified openings instead of scattered low-context listings.',
|
||||
'Status clarity - Understand where your profile and applications stand.',
|
||||
'Better first impression - Use a stronger profile setup to improve employer confidence.',
|
||||
'Structured role discovery - Explore openings by role, company intent, and fit.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical job paths on this role flow',
|
||||
typicalLeftItems: ['Full-time roles', 'Part-time roles', 'Internships', 'Entry-level opportunities', 'Specialist roles', 'Growth-stage company openings'],
|
||||
typicalRightTitle: 'What companies usually expect',
|
||||
typicalRightItems: ['Clear candidate profile', 'Skill and role alignment', 'Availability', 'Location or relocation preference', 'Portfolio or work proof where relevant', 'Prompt response'],
|
||||
howItWorksTitle: 'How joining as a Job Seeker works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your job seeker flow.' },
|
||||
{ title: 'Complete your candidate profile', description: 'Add experience, skills, role goals, and availability.' },
|
||||
{ title: 'Apply to approved jobs', description: 'Use a cleaner opportunity flow to target relevant openings.' },
|
||||
{ title: 'Track application movement', description: 'Monitor updates and response stages with more clarity.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Job Seekers choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Approved job visibility - See opportunities shaped by platform review and trust signals.',
|
||||
'Cleaner application journey - Avoid some of the noise common in open listing boards.',
|
||||
'Better tracking confidence - Understand what is happening after you apply.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Can I apply without full experience?', a: 'Yes. Different roles may fit different levels, including internships and early-career candidates.' },
|
||||
{ q: 'Why does verification matter for job seekers?', a: 'It improves trust for companies and supports cleaner matching.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile, work details, and role preferences over time.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your experience, role interests, location, availability, and proof of work when relevant.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile-related approvals are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Job Seeker profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Start as Job Seeker', href: '/signup?intent=job_seeker' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
photographer: {
|
||||
slug: 'photographer',
|
||||
roleKey: 'PHOTOGRAPHER',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Photographer',
|
||||
heroEyebrow: 'Photographer on Nxtgauge',
|
||||
heroTitle: 'Show your photography style with trust-first visibility and clearer bookings',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Photographer and present your work through a profile-led system built for trust. Build confidence faster, respond to cleaner demand, and manage request movement with more clarity.',
|
||||
heroImage: '/images/roles/photographer.jpg',
|
||||
primaryCta: { label: 'Register as Photographer', href: '/signup?intent=professional&role=PHOTOGRAPHER' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Photographer on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Photographer profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Most requested photography projects',
|
||||
typicalLeftItems: [
|
||||
'Event and corporate coverage',
|
||||
'Portrait and family sessions',
|
||||
'Brand and campaign photography',
|
||||
'Product and catalog shoots',
|
||||
'Wedding and pre-wedding shoots',
|
||||
'Social media content production',
|
||||
],
|
||||
typicalRightTitle: 'What clients compare before booking',
|
||||
typicalRightItems: [
|
||||
'Visual style and editing consistency',
|
||||
'Date and time availability',
|
||||
'Travel range and location coverage',
|
||||
'Package inclusions and pricing clarity',
|
||||
'Portfolio depth in similar projects',
|
||||
'Delivery timeline and output format',
|
||||
],
|
||||
howItWorksTitle: 'How joining as a Photographer works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your photographer profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Photographers choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified customer requirements - Designed to help photographer professionals reduce noise and focus on real demand.',
|
||||
'Cleaner demand discovery - Supports a more focused path to relevant opportunities.',
|
||||
'Better trust for first-time clients - Trust signals help customers feel more confident before first contact.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of photographer?', a: 'No. It supports different working styles and specializations within the photographer role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Photographer profile',
|
||||
finalCtaSupport: 'One account. Verified visibility.',
|
||||
finalPrimaryCta: { label: 'Register as Photographer', href: '/signup?intent=professional&role=PHOTOGRAPHER' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'makeup-artist': {
|
||||
slug: 'makeup-artist',
|
||||
roleKey: 'MAKEUP_ARTIST',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Makeup Artist',
|
||||
heroEyebrow: 'Makeup Artist on Nxtgauge',
|
||||
heroTitle: 'Grow as a Makeup Artist through profile trust and better-fit client discovery',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Makeup Artist and build a profile that helps customers trust your work before first contact. Move through a clearer request flow with stronger presentation and less low-intent noise.',
|
||||
heroImage: '/images/roles/makeup_artist.jpg',
|
||||
primaryCta: { label: 'Register as Makeup Artist', href: '/signup?intent=professional&role=MAKEUP_ARTIST' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Makeup Artist on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Makeup Artist profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Bridal makeup', 'Party makeup', 'Editorial looks', 'Event-ready styling', 'Fashion shoots', 'Occasion-based makeup services'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Look specialization', 'Travel or location support', 'Package details', 'Product/style preferences', 'Portfolio proof', 'Scheduling clarity'],
|
||||
howItWorksTitle: 'How joining as a Makeup Artist works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your makeup artist profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Makeup Artists choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified customer requirements - Designed to help makeup artist professionals reduce noise and focus on real demand.',
|
||||
'Cleaner demand discovery - Supports a more focused path to relevant opportunities.',
|
||||
'Better trust for first-time clients - Trust signals help customers feel more confident before first contact.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of makeup artist?', a: 'No. It supports different working styles and specializations within the makeup artist role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Makeup Artist profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Makeup Artist', href: '/signup?intent=professional&role=MAKEUP_ARTIST' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
tutor: {
|
||||
slug: 'tutor',
|
||||
roleKey: 'TUTOR',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Tutor',
|
||||
heroEyebrow: 'Tutor on Nxtgauge',
|
||||
heroTitle: 'Teach with stronger profile credibility and better quality learner discovery',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Tutor and present your expertise through a trust-first system. Help learners understand your subject fit, teaching format, and value more clearly before they reach out.',
|
||||
heroImage: '/images/roles/tutor.jpg',
|
||||
primaryCta: { label: 'Register as Tutor', href: '/signup?intent=professional&role=TUTOR' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Tutor on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Tutor profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['School subject tutoring', 'Exam preparation', 'Language coaching', 'Online tutoring sessions', 'Skill-based mentoring', 'Homework and concept support'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Subject specialization', 'Teaching format', 'Schedule and availability', 'Learner level fit', 'Session structure', 'Outcome clarity'],
|
||||
howItWorksTitle: 'How joining as a Tutor works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your tutor profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Tutors choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified customer requirements - Designed to help tutor professionals reduce noise and focus on real demand.',
|
||||
'Cleaner demand discovery - Supports a more focused path to relevant opportunities.',
|
||||
'Better trust for first-time clients - Trust signals help customers feel more confident before first contact.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of tutor?', a: 'No. It supports different working styles and specializations within the tutor role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Tutor profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Tutor', href: '/signup?intent=professional&role=TUTOR' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
developer: {
|
||||
slug: 'developer',
|
||||
roleKey: 'DEVELOPER',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Developer',
|
||||
heroEyebrow: 'Developer on Nxtgauge',
|
||||
heroTitle: 'Build for real client demand with a stronger developer profile',
|
||||
heroDescription: 'Show your stack clearly, get discovered faster, and respond to better-fit opportunities with less noise.',
|
||||
heroImage: '/images/roles/developer.jpg',
|
||||
primaryCta: { label: 'Register as Developer', href: '/signup?intent=professional&role=DEVELOPER' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Developer on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Developer profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Web app development', 'Landing page and website builds', 'E-commerce development', 'SaaS feature implementation', 'API or backend work', 'Maintenance and optimization'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Tech stack clarity', 'Project scope fit', 'Timeline and availability', 'Communication quality', 'Portfolio proof', 'Delivery confidence'],
|
||||
howItWorksTitle: 'How joining as a Developer works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your developer profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Developers choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Higher-intent project leads - Work with requirements that are reviewed for clarity before wider visibility.',
|
||||
'Better fit before first call - Clients can evaluate your stack, scope fit, and delivery style from your profile.',
|
||||
'Stronger conversion confidence - Trust-led presentation improves first-contact quality and reduces back-and-forth.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of developer?', a: 'No. It supports different working styles and specializations within the developer role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Developer profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Developer', href: '/signup?intent=professional&role=DEVELOPER' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'video-editor': {
|
||||
slug: 'video-editor',
|
||||
roleKey: 'VIDEO_EDITOR',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Video Editor',
|
||||
heroEyebrow: 'Video Editor on Nxtgauge',
|
||||
heroTitle: 'Turn your editing portfolio into a stronger first impression for quality clients',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Video Editor and build profile-led visibility around your editing style, turnaround strength, and service clarity. Access better-presented demand and track request progress more clearly.',
|
||||
heroImage: '/images/roles/video_editor.jpg',
|
||||
primaryCta: { label: 'Register as Video Editor', href: '/signup?intent=professional&role=VIDEO_EDITOR' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Video Editor on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Video Editor profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Short-form content editing', 'YouTube video editing', 'Ad creative editing', 'Event video edits', 'Reels and social clips', 'Corporate video post-production'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Editing style fit', 'Turnaround expectations', 'Revision structure', 'Portfolio quality', 'Format or platform knowledge', 'Communication clarity'],
|
||||
howItWorksTitle: 'How joining as a Video Editor works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your video editor profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Video Editors choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified customer requirements - Designed to help video editor professionals reduce noise and focus on real demand.',
|
||||
'Cleaner demand discovery - Supports a more focused path to relevant opportunities.',
|
||||
'Better trust for first-time clients - Trust signals help customers feel more confident before first contact.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of video editor?', a: 'No. It supports different working styles and specializations within the video editor role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Video Editor profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Video Editor', href: '/signup?intent=professional&role=VIDEO_EDITOR' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'graphic-designer': {
|
||||
slug: 'graphic-designer',
|
||||
roleKey: 'GRAPHIC_DESIGNER',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Graphic Designer',
|
||||
heroEyebrow: 'Graphic Designer on Nxtgauge',
|
||||
heroTitle: 'Present your design work with stronger trust signals and cleaner client discovery',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Graphic Designer and showcase your style through a profile-first marketplace built around trust and clarity. Reduce scattered lead noise and respond to better-fit creative opportunities.',
|
||||
heroImage: '/images/roles/graphic_designer.jpg',
|
||||
primaryCta: { label: 'Register as Graphic Designer', href: '/signup?intent=professional&role=GRAPHIC_DESIGNER' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Graphic Designer on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Graphic Designer profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Brand identity design', 'Social media creatives', 'Marketing collaterals', 'Presentation design', 'Packaging design', 'Campaign visuals'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Design style fit', 'Service scope', 'Revision structure', 'Portfolio quality', 'Timeline clarity', 'Brand understanding'],
|
||||
howItWorksTitle: 'How joining as a Graphic Designer works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your graphic designer profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Graphic Designers choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified customer requirements - Designed to help graphic designer professionals reduce noise and focus on real demand.',
|
||||
'Cleaner demand discovery - Supports a more focused path to relevant opportunities.',
|
||||
'Better trust for first-time clients - Trust signals help customers feel more confident before first contact.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of graphic designer?', a: 'No. It supports different working styles and specializations within the graphic designer role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Graphic Designer profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Graphic Designer', href: '/signup?intent=professional&role=GRAPHIC_DESIGNER' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'social-media-manager': {
|
||||
slug: 'social-media-manager',
|
||||
roleKey: 'SOCIAL_MEDIA_MANAGER',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Social Media Manager',
|
||||
heroEyebrow: 'Social Media Manager on Nxtgauge',
|
||||
heroTitle: 'Grow through trusted profile-led visibility and clearer campaign demand',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Social Media Manager and present your strategy, niche, and service model with more clarity. Build client trust faster and respond to campaign demand through a cleaner workflow.',
|
||||
heroImage: '/images/roles/social_media_manager.jpg',
|
||||
primaryCta: { label: 'Register as Social Media Manager', href: '/signup?intent=professional&role=SOCIAL_MEDIA_MANAGER' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Social Media Manager on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Social Media Manager profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Monthly social media management', 'Content planning', 'Campaign support', 'Community management', 'Growth-focused strategy', 'Platform-specific content operations'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Platform expertise', 'Industry or niche fit', 'Content process clarity', 'Reporting expectations', 'Package scope', 'Availability'],
|
||||
howItWorksTitle: 'How joining as a Social Media Manager works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your social media manager profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Social Media Managers choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified customer requirements - Designed to help social media manager professionals reduce noise and focus on real demand.',
|
||||
'Cleaner demand discovery - Supports a more focused path to relevant opportunities.',
|
||||
'Better trust for first-time clients - Trust signals help customers feel more confident before first contact.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of social media manager?', a: 'No. It supports different working styles and specializations within the social media manager role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Social Media Manager profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Social Media Manager', href: '/signup?intent=professional&role=SOCIAL_MEDIA_MANAGER' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'fitness-trainer': {
|
||||
slug: 'fitness-trainer',
|
||||
roleKey: 'FITNESS_TRAINER',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Fitness Trainer',
|
||||
heroEyebrow: 'Fitness Trainer on Nxtgauge',
|
||||
heroTitle: 'Grow as a Fitness Trainer through trusted profile-led discovery',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Fitness Trainer and connect with customers through a trust-first workflow. Build credibility, complete verification, and respond to better-fit opportunities with more clarity.',
|
||||
heroImage: '/images/roles/fitness_trainer.jpg',
|
||||
primaryCta: { label: 'Register as Fitness Trainer', href: '/signup?intent=professional&role=FITNESS_TRAINER' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Fitness Trainer on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Fitness Trainer profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Personal fitness coaching', 'Weight-loss transformation programs', 'Strength and conditioning plans', 'Online workout accountability', 'Functional training support', 'Lifestyle and routine-based fitness guidance'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Program specialization', 'Session format and schedule', 'Client readiness requirements', 'Service scope', 'Package clarity', 'Coaching style'],
|
||||
howItWorksTitle: 'How joining as a Fitness Trainer works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your fitness trainer profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Fitness Trainers choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Higher-intent client inquiries - Connect with requests that are reviewed for clarity before wider visibility.',
|
||||
'Better program-fit matching - Clients can assess your training style, specialization, and availability early.',
|
||||
'Stronger first-contact conversion - Clear trust signals help reduce drop-offs and improve booking confidence.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of fitness trainer?', a: 'No. It supports different working styles and specializations within the fitness trainer role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Fitness Trainer profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Fitness Trainer', href: '/signup?intent=professional&role=FITNESS_TRAINER' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'catering-services': {
|
||||
slug: 'catering-services',
|
||||
roleKey: 'CATERING_SERVICES',
|
||||
audience: 'professional',
|
||||
shortTitle: 'Catering Services',
|
||||
heroEyebrow: 'Catering Services on Nxtgauge',
|
||||
heroTitle: 'Showcase your menus and event readiness through a more trusted discovery flow',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a Catering Services provider and present your service quality, event readiness, and package structure more clearly. Build trust before first contact and respond to cleaner requirement demand.',
|
||||
heroImage: '/images/roles/catering_services.jpg',
|
||||
primaryCta: { label: 'Register as Catering Services', href: '/signup?intent=professional&role=CATERING_SERVICES' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a Catering Services on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Catering Services profile visibility - Show your specialization, service style, location, and strengths more clearly.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on more serious requests.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present services, proof of work, and profile strength in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Wedding catering', 'Corporate event catering', 'Birthday and private event catering', 'Buffet service packages', 'Live counter services', 'Custom event menus'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Cuisine or menu fit', 'Guest capacity', 'Package structure', 'Location coverage', 'Event readiness', 'Service inclusions'],
|
||||
howItWorksTitle: 'How joining as a Catering Services works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your catering services profile', description: 'Add service scope, working style, location, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why Catering Services choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified customer requirements - Designed to help catering services professionals reduce noise and focus on real demand.',
|
||||
'Cleaner demand discovery - Supports a more focused path to relevant opportunities.',
|
||||
'Better trust for first-time clients - Trust signals help customers feel more confident before first contact.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of catering services?', a: 'No. It supports different working styles and specializations within the catering services role.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves confidence for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your specialization, service structure, location, proof of work, and clear package details.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your Catering Services profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as Catering Services', href: '/signup?intent=professional&role=CATERING_SERVICES' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
'ugc-content-creator': {
|
||||
slug: 'ugc-content-creator',
|
||||
roleKey: 'UGC_CONTENT_CREATOR',
|
||||
audience: 'professional',
|
||||
shortTitle: 'UGC Content Creator',
|
||||
heroEyebrow: 'UGC Content Creator on Nxtgauge',
|
||||
heroTitle: 'Grow your creator profile with trust-first visibility and cleaner campaign demand',
|
||||
heroDescription:
|
||||
'Join Nxtgauge as a UGC Content Creator and showcase your campaign style, content niche, and delivery model in a trust-led workflow built for better-fit collaborations.',
|
||||
heroImage: '/images/roles/social_media_manager.jpg',
|
||||
primaryCta: { label: 'Register as UGC Content Creator', href: '/signup?intent=professional&role=UGC_CONTENT_CREATOR' },
|
||||
secondaryCta: { label: 'View All Professionals', href: '/professionals' },
|
||||
whatYouGetTitle: 'What you get as a UGC Content Creator on Nxtgauge',
|
||||
whatYouGetSubtitle: 'Practical platform value focused on stronger trust, clearer discovery, and better conversion quality.',
|
||||
whatYouGetCards: [
|
||||
'Creator profile visibility - Present your content niche, style, and strengths with clarity.',
|
||||
'Trust-led discovery - Appear in a marketplace designed to prioritize verified interactions.',
|
||||
'Cleaner demand flow - Reduce low-intent noise and focus on stronger collaboration signals.',
|
||||
'Status clarity - Track request movement and response progress more clearly.',
|
||||
'Better first impression - Use approval and profile trust signals to improve confidence.',
|
||||
'Structured opportunity access - Present proof of work and campaign-fit signals in one place.',
|
||||
],
|
||||
typicalLeftTitle: 'Typical projects from this role',
|
||||
typicalLeftItems: ['Product demo UGC videos', 'Lifestyle brand content', 'Testimonial and review scripts', 'Campaign creative batches', 'Reels and short-form deliverables', 'Performance-oriented content iterations'],
|
||||
typicalRightTitle: 'What customers usually expect',
|
||||
typicalRightItems: ['Niche and style fit', 'Deliverable structure', 'Timeline clarity', 'Revision expectations', 'Usage rights understanding', 'Communication quality'],
|
||||
howItWorksTitle: 'How joining as a UGC Content Creator works',
|
||||
howItWorksSteps: [
|
||||
{ title: 'Create one account', description: 'Sign up once and start your professional onboarding.' },
|
||||
{ title: 'Complete your creator profile', description: 'Add niche, service scope, style, and package details.' },
|
||||
{ title: 'Submit for verification', description: 'Your role details are reviewed before visibility expands.' },
|
||||
{ title: 'Start responding to opportunities', description: 'Track request flow and engage with clearer, trust-backed demand.' },
|
||||
],
|
||||
whyChooseTitle: 'Why UGC Creators choose Nxtgauge',
|
||||
whyChooseCards: [
|
||||
'Verified campaign demand - Designed to reduce low-intent discovery noise.',
|
||||
'Cleaner collaboration flow - Supports clearer matching between creator style and requirement.',
|
||||
'Better trust for first-time brands - Trust signals improve first-contact confidence.',
|
||||
],
|
||||
faqs: [
|
||||
{ q: 'Is this only for one type of UGC creator?', a: 'No. It supports creators across different niches and campaign formats.' },
|
||||
{ q: 'Why does verification matter for this role?', a: 'It improves trust for customers and reduces low-intent interactions.' },
|
||||
{ q: 'What should I include in my profile?', a: 'Add your niche, service structure, location, proof of work, and package clarity.' },
|
||||
{ q: 'Can I update my profile later?', a: 'Yes. You can improve your profile and service details over time.' },
|
||||
{ q: 'How long does approval usually take?', a: 'Most profile reviews are completed within 24-48 hours.' },
|
||||
],
|
||||
finalCtaHeading: 'Build your UGC Content Creator profile and unlock better-fit opportunities',
|
||||
finalCtaSupport: 'One account. Clear verification path. Better visibility through trusted discovery.',
|
||||
finalPrimaryCta: { label: 'Register as UGC Content Creator', href: '/signup?intent=professional&role=UGC_CONTENT_CREATOR' },
|
||||
finalSecondaryCta: { label: 'Explore Other Categories', href: '/professionals' },
|
||||
},
|
||||
};
|
||||
|
||||
export const roleLandingPages = Object.values(bySlug);
|
||||
|
||||
export function getRoleLandingBySlug(slug: string): RoleLandingContent | undefined {
|
||||
return bySlug[String(slug || '').toLowerCase()];
|
||||
}
|
||||
|
||||
export function getProfessionalLandingBySlug(slug: string): RoleLandingContent | undefined {
|
||||
const item = getRoleLandingBySlug(slug);
|
||||
if (!item || item.audience !== 'professional') return undefined;
|
||||
return item;
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { A, useParams } from '@solidjs/router';
|
||||
import { Show, For, createSignal, createResource, onCleanup, onMount } from 'solid-js';
|
||||
import { fetchArticleBySlug } from '~/lib/help-center';
|
||||
import { Meta, Title } from '@solidjs/meta';
|
||||
import { Show, For, createSignal, createResource, onCleanup, onMount, createMemo } from 'solid-js';
|
||||
import { fetchArticleBySlug, fetchRelatedArticles } from '~/lib/help-center';
|
||||
import PublicBackground from '~/components/PublicBackground';
|
||||
import PublicHeader from '~/components/PublicHeader';
|
||||
import PublicFooter from '~/components/PublicFooter';
|
||||
|
|
@ -15,9 +16,23 @@ function categoryTitle(input: string) {
|
|||
|
||||
export default function HelpCenterArticlePage() {
|
||||
const params = useParams();
|
||||
const slug = createMemo(() => String(params.slug || '').trim());
|
||||
const [scrollY, setScrollY] = createSignal(0);
|
||||
|
||||
const [article] = createResource(() => params.slug, fetchArticleBySlug);
|
||||
const [relatedArticles] = createResource(
|
||||
() => article(),
|
||||
(item) => (item ? fetchRelatedArticles({ article: item, limit: 4 }) : [])
|
||||
);
|
||||
const canonical = createMemo(() => `https://test121.nxtgauge.com/help-center/article/${encodeURIComponent(slug())}`);
|
||||
const pageTitle = createMemo(() => {
|
||||
const a = article();
|
||||
return a ? `${a.title} | Nxtgauge Help Center` : 'Help Center Article | Nxtgauge';
|
||||
});
|
||||
const pageDescription = createMemo(() => {
|
||||
const a = article();
|
||||
return a?.summary || 'Read support and product guidance from Nxtgauge Help Center.';
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
const onScroll = () => setScrollY(window.scrollY || 0);
|
||||
|
|
@ -28,6 +43,17 @@ export default function HelpCenterArticlePage() {
|
|||
|
||||
return (
|
||||
<main class="lp-main">
|
||||
<Title>{pageTitle()}</Title>
|
||||
<Meta name="description" content={pageDescription()} />
|
||||
<Meta property="og:title" content={pageTitle()} />
|
||||
<Meta property="og:description" content={pageDescription()} />
|
||||
<Meta property="og:type" content="article" />
|
||||
<Meta property="og:url" content={canonical()} />
|
||||
<Meta name="twitter:card" content="summary_large_image" />
|
||||
<Meta name="twitter:title" content={pageTitle()} />
|
||||
<Meta name="twitter:description" content={pageDescription()} />
|
||||
<link rel="canonical" href={canonical()} />
|
||||
|
||||
<PublicBackground scrollY={scrollY()} />
|
||||
<div class="lp-content">
|
||||
<PublicHeader />
|
||||
|
|
@ -84,6 +110,25 @@ export default function HelpCenterArticlePage() {
|
|||
|
||||
<section class="public-section scene-dark">
|
||||
<div class="container panel panel-light" style={{ 'max-width': '960px' }}>
|
||||
<Show when={(relatedArticles() || []).length > 0}>
|
||||
<div style={{ 'margin-bottom': '20px' }}>
|
||||
<h2 style={{ margin: '0 0 10px', 'font-size': '22px' }}>Related Articles</h2>
|
||||
<div style={{ display: 'grid', gap: '10px' }}>
|
||||
<For each={relatedArticles() || []}>
|
||||
{(related) => (
|
||||
<A href={`/help-center/article/${related.slug}`} style={{ 'text-decoration': 'none' }}>
|
||||
<article style={{ border: '1px solid rgba(255,255,255,0.16)', 'border-radius': '12px', padding: '12px 14px', background: 'rgba(255,255,255,0.02)' }}>
|
||||
<p style={{ margin: 0, color: '#fd6116', 'font-size': '11px', 'font-weight': '700' }}>{related.category || 'General'}</p>
|
||||
<h3 style={{ margin: '5px 0 4px', color: '#fff', 'font-size': '16px' }}>{related.title}</h3>
|
||||
<p style={{ margin: 0, color: 'rgba(255,255,255,0.75)', 'font-size': '13px' }}>{related.summary}</p>
|
||||
</article>
|
||||
</A>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<h2>Need more help?</h2>
|
||||
<p class="sub">
|
||||
If this article does not solve your issue, send your question with context to support.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { A } from '@solidjs/router';
|
||||
import { Meta, Title } from '@solidjs/meta';
|
||||
import { For, createResource, createSignal } from 'solid-js';
|
||||
import PublicBackground from '~/components/PublicBackground';
|
||||
import PublicFooter from '~/components/PublicFooter';
|
||||
|
|
@ -6,6 +7,9 @@ import PublicHeader from '~/components/PublicHeader';
|
|||
import { fetchHelpCenterArticles, fetchHelpCenterCategories } from '~/lib/help-center';
|
||||
|
||||
export default function HelpCenterPage() {
|
||||
const title = 'Help Center | Nxtgauge';
|
||||
const description = 'Browse Nxtgauge guides for getting started, roles, requests, approvals, and platform troubleshooting.';
|
||||
const canonical = 'https://test121.nxtgauge.com/help-center';
|
||||
const [query, setQuery] = createSignal('');
|
||||
const [category, setCategory] = createSignal('');
|
||||
|
||||
|
|
@ -17,6 +21,17 @@ export default function HelpCenterPage() {
|
|||
|
||||
return (
|
||||
<main class="lp-main">
|
||||
<Title>{title}</Title>
|
||||
<Meta name="description" content={description} />
|
||||
<Meta property="og:title" content={title} />
|
||||
<Meta property="og:description" content={description} />
|
||||
<Meta property="og:type" content="website" />
|
||||
<Meta property="og:url" content={canonical} />
|
||||
<Meta name="twitter:card" content="summary_large_image" />
|
||||
<Meta name="twitter:title" content={title} />
|
||||
<Meta name="twitter:description" content={description} />
|
||||
<link rel="canonical" href={canonical} />
|
||||
|
||||
<PublicBackground />
|
||||
<div class="lp-content">
|
||||
<PublicHeader />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,24 @@
|
|||
import { Meta, Title } from '@solidjs/meta';
|
||||
import PublicLanding from '~/components/PublicLanding';
|
||||
|
||||
export default function Home() {
|
||||
return <PublicLanding />;
|
||||
const title = 'Nxtgauge | Verified Jobs & Professional Services Platform';
|
||||
const description = 'Trusted hiring and opportunity discovery for customers, companies, professionals, and job seekers with verification built in.';
|
||||
const canonical = 'https://test121.nxtgauge.com/';
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title>{title}</Title>
|
||||
<Meta name="description" content={description} />
|
||||
<Meta property="og:title" content={title} />
|
||||
<Meta property="og:description" content={description} />
|
||||
<Meta property="og:type" content="website" />
|
||||
<Meta property="og:url" content={canonical} />
|
||||
<Meta name="twitter:card" content="summary_large_image" />
|
||||
<Meta name="twitter:title" content={title} />
|
||||
<Meta name="twitter:description" content={description} />
|
||||
<link rel="canonical" href={canonical} />
|
||||
<PublicLanding />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
7
src/routes/professionals/[slug].tsx
Normal file
7
src/routes/professionals/[slug].tsx
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { useParams } from '@solidjs/router';
|
||||
import RoleLandingPage from '~/components/RoleLandingPage';
|
||||
|
||||
export default function ProfessionalDetailPage() {
|
||||
const params = useParams();
|
||||
return <RoleLandingPage slug={String(params.slug || '')} pathBase="/professionals" audience="professional" />;
|
||||
}
|
||||
124
src/routes/professionals/index.tsx
Normal file
124
src/routes/professionals/index.tsx
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
import { A } from '@solidjs/router';
|
||||
import { Meta, Title } from '@solidjs/meta';
|
||||
import { For, createSignal, onCleanup, onMount } from 'solid-js';
|
||||
import PublicFooter from '~/components/PublicFooter';
|
||||
import PublicHeader from '~/components/PublicHeader';
|
||||
import { professionalPages, professionalSignupHref } from '~/lib/professionals';
|
||||
|
||||
const chipNodes = [
|
||||
{ left: '10%', top: '18%', size: 32, cls: 'lp-chip-slow', label: '★' },
|
||||
{ left: '31%', top: '8%', size: 36, cls: 'lp-chip-mid', label: '✓' },
|
||||
{ left: '82%', top: '12%', size: 34, cls: 'lp-chip-fast', label: '↗' },
|
||||
{ left: '72%', top: '34%', size: 30, cls: 'lp-chip-mid', label: '✦' },
|
||||
{ left: '16%', top: '62%', size: 36, cls: 'lp-chip-fast', label: '⚑' },
|
||||
{ left: '63%', top: '72%', size: 32, cls: 'lp-chip-slow', label: '⎈' },
|
||||
] as const;
|
||||
|
||||
export default function ProfessionalsIndexPage() {
|
||||
const [scrollY, setScrollY] = createSignal(0);
|
||||
const [reduceMotion, setReduceMotion] = createSignal(false);
|
||||
const canonical = 'https://test121.nxtgauge.com/professionals';
|
||||
const title = 'Professionals | Nxtgauge Verified Service Categories';
|
||||
const description = 'Explore verified professional categories on Nxtgauge and register with a trust-first workflow built for better opportunity quality.';
|
||||
|
||||
onMount(() => {
|
||||
const media = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
const sync = () => setReduceMotion(media.matches);
|
||||
sync();
|
||||
const onScroll = () => setScrollY(window.scrollY || 0);
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
media.addEventListener('change', sync);
|
||||
onCleanup(() => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
media.removeEventListener('change', sync);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<main class="lp-main">
|
||||
<Title>{title}</Title>
|
||||
<Meta name="description" content={description} />
|
||||
<Meta property="og:title" content={title} />
|
||||
<Meta property="og:description" content={description} />
|
||||
<Meta property="og:type" content="website" />
|
||||
<Meta property="og:url" content={canonical} />
|
||||
<Meta name="twitter:card" content="summary_large_image" />
|
||||
<Meta name="twitter:title" content={title} />
|
||||
<Meta name="twitter:description" content={description} />
|
||||
<link rel="canonical" href={canonical} />
|
||||
|
||||
<div class="lp-bg" aria-hidden="true">
|
||||
<div class="lp-dark-base" />
|
||||
<div class="lp-mesh" style={{ transform: `translate3d(0, ${reduceMotion() ? 0 : Math.min(36, scrollY() * 0.1)}px, 0)` }} />
|
||||
<div class="lp-ribbon" style={{ transform: `translate3d(0, ${reduceMotion() ? 0 : Math.min(58, scrollY() * 0.18)}px, 0)` }} />
|
||||
<div class="lp-chips" style={{ transform: `translate3d(0, ${reduceMotion() ? 0 : Math.min(80, scrollY() * 0.24)}px, 0)` }}>
|
||||
<For each={chipNodes}>
|
||||
{(chip) => (
|
||||
<span class={`lp-chip ${chip.cls}`} style={{ left: chip.left, top: chip.top, width: `${chip.size}px`, height: `${chip.size}px` }}>
|
||||
<span class="pro-detail-bg-chip-icon">{chip.label}</span>
|
||||
</span>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div class="lp-noise" />
|
||||
</div>
|
||||
<div class="lp-content">
|
||||
<PublicHeader />
|
||||
|
||||
<section class="public-section lp-section-hero">
|
||||
<div class="container lp-hero-grid">
|
||||
<div>
|
||||
<p class="eyebrow">Professionals</p>
|
||||
<h1 class="lp-hero-title" style="font-size:clamp(32px,4.6vw,52px)">Explore professional categories on Nxtgauge</h1>
|
||||
<p class="lp-hero-copy">
|
||||
Choose your category, understand what Nxtgauge offers for your role, and register with a trust-first workflow.
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<A class="lp-primary-btn" href="/signup?intent=professional">Get Started</A>
|
||||
<A class="lp-ghost-btn lp-ghost-btn-dark" href="/professionals#paths">View categories</A>
|
||||
</div>
|
||||
<p class="lp-hero-note">Dedicated role pages are optimized for campaign traffic and search visibility.</p>
|
||||
</div>
|
||||
<div class="lp-hero-graph">
|
||||
<img src="/images/roles/photographer.jpg" alt="Professional photography workspace setup" class="role-hero-photo" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="paths" class="public-section lp-section">
|
||||
<div class="container panel choose-path-panel">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>All professional paths</h2>
|
||||
<p class="sub">Stable landing pages for discovery, SEO, and campaign traffic.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="path-grid">
|
||||
<For each={professionalPages}>
|
||||
{(item) => (
|
||||
<article class="path-card">
|
||||
<div class="path-media">
|
||||
<img src={item.image} alt={item.shortTitle} loading="lazy" />
|
||||
<div class="path-media-overlay" />
|
||||
</div>
|
||||
<div class="path-body">
|
||||
<span class="path-chip">{item.category}</span>
|
||||
<h3>{item.shortTitle}</h3>
|
||||
<p>{item.heroDescription}</p>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:14px">
|
||||
<A class="path-secondary-btn" href={`/professionals/${item.slug}`}>Explore</A>
|
||||
<A class="path-secondary-btn" href={professionalSignupHref(item.roleKey)}>Register</A>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<PublicFooter />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
7
src/routes/roles/[slug].tsx
Normal file
7
src/routes/roles/[slug].tsx
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { useParams } from '@solidjs/router';
|
||||
import RoleLandingPage from '~/components/RoleLandingPage';
|
||||
|
||||
export default function RoleLandingRoute() {
|
||||
const params = useParams();
|
||||
return <RoleLandingPage slug={String(params.slug || '')} pathBase="/roles" />;
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ function normalizeIntent(intent: string | null | undefined): RoleKey {
|
|||
const v = String(intent || '').toLowerCase();
|
||||
if (v.includes('company')) return 'company';
|
||||
if (v.includes('professional')) return 'professional';
|
||||
if (v.includes('developer') || v.includes('photographer') || v.includes('makeup') || v.includes('tutor') || v.includes('video') || v.includes('graphic') || v.includes('social') || v.includes('fitness') || v.includes('catering') || v.includes('ugc')) return 'professional';
|
||||
if (v.includes('customer')) return 'customer';
|
||||
return 'job_seeker';
|
||||
}
|
||||
|
|
@ -57,7 +58,8 @@ export default function SignupRoute() {
|
|||
const [search] = useSearchParams();
|
||||
onMount(() => {
|
||||
const intent = String(search.intent || '').trim();
|
||||
if (!intent) navigate('/users/choose-role', { replace: true });
|
||||
const role = String(search.role || '').trim();
|
||||
if (!intent && !role) navigate('/users/choose-role', { replace: true });
|
||||
});
|
||||
|
||||
const [step, setStep] = createSignal<'register' | 'verify'>('register');
|
||||
|
|
@ -66,7 +68,8 @@ export default function SignupRoute() {
|
|||
const [email, setEmail] = createSignal('');
|
||||
const [password, setPassword] = createSignal('');
|
||||
const [confirmPassword, setConfirmPassword] = createSignal('');
|
||||
const role = createMemo<RoleKey>(() => normalizeIntent(search.intent));
|
||||
const role = createMemo<RoleKey>(() => normalizeIntent(search.intent || search.role));
|
||||
const selectedProfessionalRole = createMemo(() => String(search.role || '').trim().toUpperCase());
|
||||
const [termsAccepted, setTermsAccepted] = createSignal(false);
|
||||
const [captcha, setCaptcha] = createSignal('');
|
||||
const [captchaCode, setCaptchaCode] = createSignal(randomCaptcha());
|
||||
|
|
@ -152,6 +155,7 @@ export default function SignupRoute() {
|
|||
email: input.email.toLowerCase(),
|
||||
roleKey: input.roleKey,
|
||||
role: input.roleKey,
|
||||
selectedProfessionalRole: selectedProfessionalRole() || null,
|
||||
user: input.user || null,
|
||||
};
|
||||
if (typeof window !== 'undefined') {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue