Thoroughly audit ALL page components in /home/ccuser/the-50-dollar-app/src/app/ for bugs, broken UI, and missing functionality.

Focus on:
1. Read every page.tsx and layout.tsx file
2. Check for broken imports (components that don't exist)
3. Check for missing error handling
4. Check for hardcoded URLs or values
5. Check if forms submit to the right API endpoints
6. Check if auth state is properly handled
7. Look for any commented-out code or dead code
8. Check if loading states and error states exist
9. Look for any .backup files that shouldn't be there
10. Check the middleware.ts for route protection issues

Read every page file and report specific bugs with file paths and line numbers.


I'll conduct a thorough audit of all page components in the $50 app. Let me start by exploring the structure and reading all relevant files.


Bash

find /home/ccuser/the-50-dollar-app/src/app -type f \( -name "page.tsx" -o -name "layout.tsx" -o -name "middleware.ts" -o -name "*.backup" \) | head -50


Now let me check if there's a middleware.ts file and identify all the page files:


find /home/ccuser/the-50-dollar-app -name "middleware.ts" -o -name ".backup"


/home/ccuser/the-50-dollar-app/src/lib/supabase/middleware.ts
/home/ccuser/the-50-dollar-app/src/middleware.ts


Good! I found a backup file and middleware files. Let me now read all the page files systematically. I'll start with the main layout and middleware files, then audit each page.


     1→import { type NextRequest } from "next/server";
     2→import { updateSession } from "@/lib/supabase/middleware";
     3→
     4→export async function middleware(request: NextRequest) {
     5→  return await updateSession(request);
     6→}
     7→
     8→export const config = {
     9→  matcher: [
    10→    "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
    11→  ],
    12→};
    13→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→import type { Metadata, Viewport } from "next";
     2→import { Geist, Geist_Mono } from "next/font/google";
     3→import { Toaster } from "react-hot-toast";
     4→import "./globals.css";
     5→
     6→const geistSans = Geist({
     7→  variable: "--font-geist-sans",
     8→  subsets: ["latin"],
     9→});
    10→
    11→const geistMono = Geist_Mono({
    12→  variable: "--font-geist-mono",
    13→  subsets: ["latin"],
    14→});
    15→
    16→export const metadata: Metadata = {
    17→  title: "RateRight — Hire Construction Workers Fast",
    18→  description:
    19→    "The simplest way to hire construction workers in Australia. AI does the work, you just tap. $50 flat fee per hire.",
    20→  keywords: [
    21→    "construction hiring",
    22→    "hire labourers",
    23→    "construction workers Australia",
    24→    "hire tradies",
    25→    "construction jobs Sydney",
    26→  ],
    27→  manifest: "/manifest.json",
    28→  appleWebApp: {
    29→    capable: true,
    30→    statusBarStyle: "default",
    31→    title: "RateRight",
    32→  },
    33→  other: {
    34→    "mobile-web-app-capable": "yes",
    35→    "apple-mobile-web-app-capable": "yes",
    36→    "application-name": "RateRight",
    37→    "msapplication-starturl": "/",
    38→    "msapplication-TileColor": "#2563eb",
    39→    "theme-color": "#2563eb",
    40→  },
    41→};
    42→
    43→export const viewport: Viewport = {
    44→  width: "device-width",
    45→  initialScale: 1,
    46→  maximumScale: 1,
    47→  themeColor: "#2563eb",
    48→};
    49→
    50→export default function RootLayout({
    51→  children,
    52→}: Readonly<{
    53→  children: React.ReactNode;
    54→}>) {
    55→  return (
    56→    <html lang="en-AU">
    57→      <head>
    58→        <link rel="manifest" href="/manifest.json" />
    59→        <link rel="icon" href="/favicon.ico" sizes="any" />
    60→        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
    61→        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
    62→        <link rel="apple-touch-icon" href="/icon-144x144.png" />
    63→        <meta name="apple-mobile-web-app-status-bar-style" content="default" />
    64→        <meta name="apple-mobile-web-app-title" content="RateRight" />
    65→        <meta name="mobile-web-app-capable" content="yes" />
    66→        <meta name="apple-mobile-web-app-capable" content="yes" />
    67→        <meta name="application-name" content="RateRight" />
    68→        <meta name="msapplication-starturl" content="/" />
    69→        <meta name="msapplication-TileColor" content="#2563eb" />
    70→        <meta name="theme-color" content="#2563eb" />
    71→      </head>
    72→      <body
    73→        className={`${geistSans.variable} ${geistMono.variable} font-sans antialiased`}
    74→      >
    75→        {children}
    76→        <Toaster position="top-right" />
    77→        <script
    78→          dangerouslySetInnerHTML={{
    79→            __html: `
    80→              if ('serviceWorker' in navigator) {
    81→                window.addEventListener('load', () => {
    82→                  navigator.serviceWorker.register('/sw.js').then(
    83→                    (registration) => {
    84→                      console.log('SW registered:', registration);
    85→                    },
    86→                    (err) => {
    87→                      console.log('SW registration failed:', err);
    88→                    }
    89→                  );
    90→                });
    91→              }
    92→            `,
    93→          }}
    94→        />
    95→      </body>
    96→    </html>
    97→  );
    98→}
    99→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→import { redirect } from 'next/navigation'
     2→import { createClient } from '@/lib/supabase/server'
     3→import Link from 'next/link'
     4→import Image from 'next/image'
     5→import { SignOutButton } from '@/components/sign-out-button'
     6→import { NotificationBell } from '@/components/notification-bell'
     7→
     8→export default async function AuthenticatedLayout({
     9→  children,
    10→}: {
    11→  children: React.ReactNode
    12→}) {
    13→  const supabase = await createClient()
    14→  const { data: { user } } = await supabase.auth.getUser()
    15→
    16→  if (!user) {
    17→    redirect('/auth/login')
    18→  }
    19→
    20→  return (
    21→

    22→      {/* Header */}
    23→
    24→

    25→          <Link href="/dashboard">
    26→            <Image src="/logo_black.svg" alt="RateRight" width={120} height={34} className="h-7 w-auto" />
    27→          </Link>
    28→

    29→            {user.email}
    30→            <NotificationBell />
    31→            <SignOutButton />
    32→

    33→

    34→
    35→
    36→      {/* Main Content */}
    37→
    38→        {children}
    39→
    40→

    41→  )
    42→}
    43→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→import Link from "next/link";
     2→import Image from "next/image";
     3→import { Button } from "@/components/ui/button";
     4→import { Card, CardContent } from "@/components/ui/card";
     5→import {
     6→  Building2,
     7→  HardHat,
     8→  Zap,
     9→  DollarSign,
    10→  Shield,
    11→  CheckCircle2,
    12→  Search,
    13→  ArrowRight,
    14→  Sparkles,
    15→  MapPin,
    16→  Clock,
    17→  Users,
    18→} from "lucide-react";
    19→
    20→// Force static generation
    21→export const dynamic = 'force-static';
    22→
    23→export default function LandingPage() {
    24→  return (
    25→

    26→      {/* Orange accent bar */}
    27→

    28→
    29→      {/* Header */}
    30→
    31→

    32→          <Link href="/" className="flex items-center gap-2">
    33→            <Image src="/logo_black.svg" alt="RateRight" width={140} height={40} className="h-8 w-auto" priority />
    34→          </Link>
    35→          <Link href="/auth/login">
    36→            <Button variant="ghost" size="sm">
    37→              Sign in
    38→            </Button>
    39→          </Link>
    40→

    41→
    42→
    43→      {/* Hero */}
    44→

    45→

    46→

    47→            <MapPin className="h-3.5 w-3.5" />
    48→            Now live in Sydney
    49→

    50→
    51→

    52→            Hire construction workers{" "}
    53→            in seconds
    54→

    55→
    56→

    57→            AI builds profiles and finds matches.
    58→            You just tap hire. $50 flat fee per hire.
    59→

    60→
    61→          {/* CTA Buttons - BIG touch targets */}
    62→

    63→            <Link href="/contractor/signup">
    64→              <Button className="h-14 w-full gap-3 text-base font-semibold shadow-lg shadow-primary/25">
    65→                <Building2 className="h-6 w-6" />
    66→                I'm Hiring
    67→                <ArrowRight className="ml-auto h-5 w-5" />
    68→              </Button>
    69→            </Link>
    70→            <Link href="/worker/signup">
    71→              <Button
    72→                variant="outline"
    73→                className="h-14 w-full gap-3 border-2 text-base font-semibold"
    74→              >
    75→                <HardHat className="h-6 w-6" />
    76→                I'm Looking For Work
    77→                <ArrowRight className="ml-auto h-5 w-5" />
    78→              </Button>
    79→            </Link>
    80→

    81→
    82→

    83→            Free to sign up. Workers always free.
    84→

    85→

    86→

    87→
    88→      {/* How it works */}
    89→

    90→

    91→

    92→            How it works
    93→

    94→

    95→            Three steps. Under two minutes.
    96→

    97→
    98→

    99→            <Step
   100→              number="1"
   101→              icon={<Search className="h-5 w-5" />}
   102→              title="Tell us your company"
   103→              description="Enter your company name or ABN. AI researches your business and builds your profile automatically."
   104→            />
   105→            <Step
   106→              number="2"
   107→              icon={<Sparkles className="h-5 w-5" />}
   108→              title="AI finds the best matches"
   109→              description="Post a job in 60 seconds. Smart matching ranks workers by distance, experience, and ratings."
   110→            />
   111→            <Step
   112→              number="3"
   113→              icon={<CheckCircle2 className="h-5 w-5" />}
   114→              title="One tap to hire"
   115→              description="See top matches, tap hire, worker accepts. $50 flat fee — only charged when you hire."
   116→            />
   117→

   118→

   119→

   120→
   121→      {/* For Contractors */}
   122→

   123→

   124→

   125→            <Building2 className="h-5 w-5 text-primary" />
   126→
For Contractors

   127→

   128→

   129→            Stop wasting time hiring
   130→

   131→
   132→

   133→            <FeatureCard
   134→              icon={<Zap className="h-5 w-5 text-primary" />}
   135→              title="AI does the work"
   136→              description="Company research, job descriptions, worker matching — all automated."
   137→            />
   138→            <FeatureCard
   139→              icon={<DollarSign className="h-5 w-5 text-primary" />}
   140→              title="$50 flat fee per hire"
   141→              description="No subscriptions, no percentages. Free to post. Only pay when you hire."
   142→            />
   143→            <FeatureCard
   144→              icon={<Shield className="h-5 w-5 text-primary" />}
   145→              title="Verified workers"
   146→              description="White Card verification, ratings, and real experience on every profile."
   147→            />
   148→            <FeatureCard
   149→              icon={<Clock className="h-5 w-5 text-primary" />}
   150→              title="Hire by tomorrow"
   151→              description="Post a job now, get matched in minutes. Workers on site tomorrow."
   152→            />
   153→

   154→

   155→

   156→
   157→      {/* For Workers */}
   158→

   159→

   160→

   161→            <HardHat className="h-5 w-5 text-primary" />
   162→
For Workers

   163→

   164→

   165→            Get on a job fast
   166→

   167→

   168→            Sign up free. Get matched to jobs near you. Know what you'll earn.
   169→

   170→
   171→

   172→            <Benefit
   173→              icon={<DollarSign className="h-4 w-4" />}
   174→              text="Always free — $0 to sign up, $0 to get hired"
   175→            />
   176→            <Benefit
   177→              icon={<Clock className="h-4 w-4" />}
   178→              text="Answer 5 questions, your profile is done in 2 minutes"
   179→            />
   180→            <Benefit
   181→              icon={<MapPin className="h-4 w-4" />}
   182→              text="Get matched to jobs within kilometres of you"
   183→            />
   184→            <Benefit
   185→              icon={<Users className="h-4 w-4" />}
   186→              text="See the pay rate upfront — no guessing"
   187→            />
   188→

   189→
   190→          <Link href="/worker/signup">
   191→            <Button className="mt-8 h-12 w-full gap-2 text-base font-semibold">
   192→              <HardHat className="h-5 w-5" />
   193→              Sign up free
   194→            </Button>
   195→          </Link>
   196→

   197→

   198→
   199→      {/* Pricing */}
   200→

   201→

   202→
Simple pricing

   203→

   204→            No hidden fees. No lock-in. No percentages.
   205→

   206→
   207→          <Card className="mt-6 border-2 border-primary/20">
   208→            <CardContent className="pt-8 pb-8">
   209→
$50

   210→

   211→                per hire — that's it
   212→

   213→

   214→                <BenefitCheck text="Free to post jobs" />
   215→                <BenefitCheck text="Free to browse workers" />
   216→                <BenefitCheck text="Free for workers — always" />
   217→                <BenefitCheck text="Only pay when you confirm a hire" />
   218→                <BenefitCheck text="No monthly subscriptions" />
   219→

   220→            </CardContent>
   221→          </Card>
   222→

   223→

   224→
   225→      {/* Final CTA */}
   226→

   227→

   228→
Ready to hire smarter?

   229→

   230→            Join Sydney contractors already using RateRight.
   231→

   232→

   233→            <Link href="/contractor/signup" className="w-full sm:w-auto">
   234→              <Button
   235→                variant="secondary"
   236→                className="h-12 w-full gap-2 text-base font-semibold"
   237→              >
   238→                <Building2 className="h-5 w-5" />
   239→                Start hiring
   240→              </Button>
   241→            </Link>
   242→            <Link href="/worker/signup" className="w-full sm:w-auto">
   243→              <Button
   244→                variant="secondary"
   245→                className="h-12 w-full gap-2 text-base font-semibold"
   246→              >
   247→                <HardHat className="h-5 w-5" />
   248→                Find work
   249→              </Button>
   250→            </Link>
   251→

   252→

   253→

   254→
   255→      {/* Footer */}
   256→
   257→

   258→

   259→

   260→              <Image src="/logo_black.svg" alt="RateRight" width={110} height={32} className="h-6 w-auto" />
   261→

   262→

   263→              <Link href="/faq" className="hover:text-foreground">
   264→                FAQ
   265→              </Link>
   266→
   270→                Contact
   271→
   272→

   273→

   274→

   275→            The simplest way to hire construction workers in Australia.
   276→

   277→

   278→            © {new Date().getFullYear()} RateRight Pty Ltd. All rights
   279→            reserved.
   280→

   281→

   282→
   283→

   284→  );
   285→}
   286→
   287→function Step({
   288→  number,
   289→  icon,
   290→  title,
   291→  description,
   292→}: {
   293→  number: string;
   294→  icon: React.ReactNode;
   295→  title: string;
   296→  description: string;
   297→}) {
   298→  return (
   299→

   300→

   301→        {number}
   302→

   303→

   304→

   305→          {icon}
   306→
{title}

   307→

   308→

   309→          {description}
   310→

   311→

   312→

   313→  );
   314→}
   315→
   316→function FeatureCard({
   317→  icon,
   318→  title,
   319→  description,
   320→}: {
   321→  icon: React.ReactNode;
   322→  title: string;
   323→  description: string;
   324→}) {
   325→  return (
   326→

   327→
{icon}

   328→

   329→
{title}

   330→
{description}

   331→

   332→

   333→  );
   334→}
   335→
   336→function Benefit({
   337→  icon,
   338→  text,
   339→}: {
   340→  icon: React.ReactNode;
   341→  text: string;
   342→}) {
   343→  return (
   344→

   345→
{icon}

   346→      {text}
   347→

   348→  );
   349→}
   350→
   351→function BenefitCheck({ text }: { text: string }) {
   352→  return (
   353→

   354→      <CheckCircle2 className="h-4 w-4 shrink-0 text-primary" />
   355→      {text}
   356→

   357→  );
   358→}
   359→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Now let me read all the page files. I'll do them in batches:


1→"use client";
     2→
     3→import { useState } from "react";
     4→import { useRouter } from "next/navigation";
     5→import Link from "next/link";
     6→import { createClient } from "@/lib/supabase/client";
     7→import { Button } from "@/components/ui/button";
     8→import { Input } from "@/components/ui/input";
     9→import { Label } from "@/components/ui/label";
    10→import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
    11→
    12→export default function LoginPage() {
    13→  const [email, setEmail] = useState("");
    14→  const [password, setPassword] = useState("");
    15→  const [error, setError] = useState<string | null>(null);
    16→  const [loading, setLoading] = useState(false);
    17→  const router = useRouter();
    18→  const supabase = createClient();
    19→
    20→  async function handleLogin(e: React.FormEvent) {
    21→    e.preventDefault();
    22→    setLoading(true);
    23→    setError(null);
    24→
    25→    const { data, error } = await supabase.auth.signInWithPassword({
    26→      email,
    27→      password,
    28→    });
    29→
    30→    if (error) {
    31→      setError(error.message);
    32→      setLoading(false);
    33→      return;
    34→    }
    35→
    36→    // Check if email is verified before allowing dashboard access
    37→    if (data.user && !data.user.email_confirmed_at) {
    38→      router.push("/auth/verify-email");
    39→      router.refresh();
    40→      return;
    41→    }
    42→
    43→    router.push("/dashboard");
    44→    router.refresh();
    45→  }
    46→
    47→  return (
    48→

    49→      <Card className="w-full max-w-md">
    50→        <CardHeader className="text-center">
    51→          <CardTitle className="text-2xl font-bold">Welcome back</CardTitle>
    52→          <CardDescription>Sign in to your RateRight account</CardDescription>
    53→        </CardHeader>
    54→        <CardContent>
    55→          <form onSubmit={handleLogin} className="space-y-4">
    56→

    57→              Email
    58→              <Input
    59→                id="email"
    60→                type="email"
    61→                placeholder="you@example.com"
    62→                value={email}
    63→                onChange={(e) => setEmail(e.target.value)}
    64→                required
    65→                autoComplete="email"
    66→                className="h-12 text-base"
    67→              />
    68→

    69→

    70→              Password
    71→              <Input
    72→                id="password"
    73→                type="password"
    74→                placeholder="Your password"
    75→                value={password}
    76→                onChange={(e) => setPassword(e.target.value)}
    77→                required
    78→                autoComplete="current-password"
    79→                className="h-12 text-base"
    80→              />
    81→

    82→

    83→              <Link href="/auth/forgot-password" className="text-sm text-primary underline hover:no-underline">
    84→                Forgot password?
    85→              </Link>
    86→

    87→            {error && (
    88→

    89→
{error}

    90→

    91→            )}
    92→            <Button type="submit" className="w-full h-12 text-base font-semibold" disabled={loading}>
    93→              {loading ? "Signing in..." : "Sign in"}
    94→            </Button>
    95→          </form>
    96→

    97→            Don't have an account?{" "}
    98→            <Link href="/auth/signup" className="text-primary underline hover:no-underline">
    99→              Sign up
   100→            </Link>
   101→

   102→        </CardContent>
   103→      </Card>
   104→

   105→  );
   106→}
   107→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→"use client";
     2→import { useState } from "react";
     3→import { useRouter } from "next/navigation";
     4→import Link from "next/link";
     5→import { createClient } from "@/lib/supabase/client";
     6→import { Button } from "@/components/ui/button";
     7→import { Input } from "@/components/ui/input";
     8→import { Label } from "@/components/ui/label";
     9→import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
    10→import { HardHat, Building2 } from "lucide-react";
    11→import type { UserType } from "@/lib/types";
    12→
    13→export default function SignupPage() {
    14→  const [email, setEmail] = useState("");
    15→  const [password, setPassword] = useState("");
    16→  const [userType, setUserType] = useState<UserType | null>(null);
    17→  const [agreedToTerms, setAgreedToTerms] = useState(false);
    18→  const [error, setError] = useState<string | null>(null);
    19→  const [loading, setLoading] = useState(false);
    20→  const router = useRouter();
    21→  const supabase = createClient();
    22→
    23→  async function handleSignup(e: React.FormEvent) {
    24→    e.preventDefault();
    25→    if (!userType) {
    26→      setError("Please select whether you're hiring or looking for work");
    27→      return;
    28→    }
    29→    if (!agreedToTerms) {
    30→      setError("Please agree to the Terms of Service and Privacy Policy");
    31→      return;
    32→    }
    33→
    34→    setLoading(true);
    35→    setError(null);
    36→
    37→    const { error } = await supabase.auth.signUp({
    38→      email,
    39→      password,
    40→      options: {
    41→        data: { type: userType },
    42→        emailRedirectTo: `${window.location.origin}/auth/callback`,
    43→      },
    44→    });
    45→
    46→    if (error) {
    47→      setError(error.message);
    48→      setLoading(false);
    49→      return;
    50→    }
    51→
    52→    // Redirect to email verification page instead of dashboard
    53→    router.push("/auth/verify-email");
    54→    router.refresh();
    55→  }
    56→
    57→  return (
    58→

    59→      <Card className="w-full max-w-md">
    60→        <CardHeader className="text-center">
    61→          <CardTitle className="text-2xl font-bold">Create your account</CardTitle>
    62→          <CardDescription>
    63→            Sign up to find work or hire workers
    64→          </CardDescription>
    65→        </CardHeader>
    66→        <CardContent>
    67→          <form onSubmit={handleSignup} className="space-y-4">
    68→

    69→

    70→                Email
    71→                <Input
    72→                  id="email"
    73→                  type="email"
    74→                  value={email}
    75→                  onChange={(e) => setEmail(e.target.value)}
    76→                  required
    77→                  placeholder="you@example.com"
    78→                  className="h-12 text-base"
    79→                />
    80→

    81→

    82→                Password
    83→                <Input
    84→                  id="password"
    85→                  type="password"
    86→                  value={password}
    87→                  onChange={(e) => setPassword(e.target.value)}
    88→                  required
    89→                  placeholder="Create a password"
    90→                  minLength={6}
    91→                  className="h-12 text-base"
    92→                />
    93→

    94→

    95→
    96→

    97→              I am a...
    98→

    99→                <Button
   100→                  type="button"
   101→                  variant={userType === "contractor" ? "default" : "outline"}
   102→                  onClick={() => setUserType("contractor")}
   103→                  className="h-24 flex-col gap-2"
   104→                >
   105→                  <Building2 className="h-6 w-6" />
   106→                  Contractor
   107→                  Hiring workers
   108→                </Button>
   109→                <Button
   110→                  type="button"
   111→                  variant={userType === "worker" ? "default" : "outline"}
   112→                  onClick={() => setUserType("worker")}
   113→                  className="h-24 flex-col gap-2"
   114→                >
   115→                  <HardHat className="h-6 w-6" />
   116→                  Worker
   117→                  Looking for work
   118→                </Button>
   119→

   120→

   121→
   122→

   123→              <input
   124→                type="checkbox"
   125→                id="terms"
   126→                checked={agreedToTerms}
   127→                onChange={(e) => setAgreedToTerms(e.target.checked)}
   128→                className="mt-1 h-4 w-4 rounded border-border accent-primary"
   129→              />
   130→
   131→                I agree to the{" "}
   132→                <Link href="/legal/terms-of-service" className="text-primary underline hover:no-underline" target="_blank">
   133→                  Terms of Service
   134→                </Link>{" "}
   135→                and{" "}
   136→                <Link href="/legal/privacy-policy" className="text-primary underline hover:no-underline" target="_blank">
   137→                  Privacy Policy
   138→                </Link>
   139→
   140→

   141→
   142→            {error && (
   143→

   144→
{error}

   145→

   146→            )}
   147→
   148→            <Button type="submit" className="w-full h-12 text-base font-semibold" disabled={loading || !agreedToTerms}>
   149→              {loading ? "Creating account..." : "Create account"}
   150→            </Button>
   151→
   152→

   153→              Already have an account?{" "}
   154→              <Link href="/auth/login" className="text-primary underline hover:no-underline">
   155→                Sign in
   156→              </Link>
   157→

   158→          </form>
   159→        </CardContent>
   160→      </Card>
   161→

   162→  );
   163→}
   164→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→"use client";
     2→
     3→import { useState } from "react";
     4→import Link from "next/link";
     5→import { createClient } from "@/lib/supabase/client";
     6→import { Button } from "@/components/ui/button";
     7→import { Input } from "@/components/ui/input";
     8→import { Label } from "@/components/ui/label";
     9→import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
    10→import { Mail, CheckCircle2 } from "lucide-react";
    11→
    12→export default function ForgotPasswordPage() {
    13→  const [email, setEmail] = useState("");
    14→  const [error, setError] = useState<string | null>(null);
    15→  const [loading, setLoading] = useState(false);
    16→  const [emailSent, setEmailSent] = useState(false);
    17→  const supabase = createClient();
    18→
    19→  async function handleSubmit(e: React.FormEvent) {
    20→    e.preventDefault();
    21→    setLoading(true);
    22→    setError(null);
    23→
    24→    const { error } = await supabase.auth.resetPasswordForEmail(email, {
    25→      redirectTo: `${window.location.origin}/auth/callback?next=/auth/reset-password`,
    26→    });
    27→
    28→    if (error) {
    29→      setError(error.message);
    30→      setLoading(false);
    31→      return;
    32→    }
    33→
    34→    setEmailSent(true);
    35→    setLoading(false);
    36→  }
    37→
    38→  if (emailSent) {
    39→    return (
    40→

    41→        <Card className="w-full max-w-md">
    42→          <CardHeader className="text-center">
    43→

    44→              <Mail className="h-6 w-6 text-primary" />
    45→

    46→            <CardTitle className="text-2xl font-bold">Check your email</CardTitle>
    47→            <CardDescription className="mt-2">
    48→              We've sent a password reset link to {email}. Click the link in the email to reset your password.
    49→            </CardDescription>
    50→          </CardHeader>
    51→          <CardContent className="space-y-3">
    52→

    53→

    54→                <CheckCircle2 className="h-4 w-4 text-green-600 shrink-0" />
    55→
Reset link sent

    56→

    57→

    58→            <Button
    59→              onClick={() => { setEmailSent(false); setEmail(""); }}
    60→              variant="outline"
    61→              className="w-full h-12 text-base"
    62→            >
    63→              Try a different email
    64→            </Button>
    65→            <Button
    66→              asChild
    67→              variant="ghost"
    68→              className="w-full h-12 text-base"
    69→            >
    70→              <Link href="/auth/login">Back to login</Link>
    71→            </Button>
    72→          </CardContent>
    73→        </Card>
    74→

    75→    );
    76→  }
    77→
    78→  return (
    79→

    80→      <Card className="w-full max-w-md">
    81→        <CardHeader className="text-center">
    82→          <CardTitle className="text-2xl font-bold">Reset your password</CardTitle>
    83→          <CardDescription>Enter your email and we'll send you a reset link</CardDescription>
    84→        </CardHeader>
    85→        <CardContent>
    86→          <form onSubmit={handleSubmit} className="space-y-4">
    87→

    88→              Email
    89→              <Input
    90→                id="email"
    91→                type="email"
    92→                placeholder="you@example.com"
    93→                value={email}
    94→                onChange={(e) => setEmail(e.target.value)}
    95→                required
    96→                autoComplete="email"
    97→                className="h-12 text-base"
    98→              />
    99→

   100→            {error && (
   101→

   102→
{error}

   103→

   104→            )}
   105→            <Button type="submit" className="w-full h-12 text-base font-semibold" disabled={loading}>
   106→              {loading ? "Sending..." : "Send reset link"}
   107→            </Button>
   108→          </form>
   109→

   110→            Remember your password?{" "}
   111→            <Link href="/auth/login" className="text-primary underline hover:no-underline">
   112→              Sign in
   113→            </Link>
   114→

   115→        </CardContent>
   116→      </Card>
   117→

   118→  );
   119→}
   120→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→"use client";
     2→
     3→import { useState } from "react";
     4→import { useRouter } from "next/navigation";
     5→import Link from "next/link";
     6→import { createClient } from "@/lib/supabase/client";
     7→import { Button } from "@/components/ui/button";
     8→import { Input } from "@/components/ui/input";
     9→import { Label } from "@/components/ui/label";
    10→import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
    11→import { CheckCircle2 } from "lucide-react";
    12→
    13→export default function ResetPasswordPage() {
    14→  const [password, setPassword] = useState("");
    15→  const [confirmPassword, setConfirmPassword] = useState("");
    16→  const [error, setError] = useState<string | null>(null);
    17→  const [loading, setLoading] = useState(false);
    18→  const [success, setSuccess] = useState(false);
    19→  const router = useRouter();
    20→  const supabase = createClient();
    21→
    22→  async function handleReset(e: React.FormEvent) {
    23→    e.preventDefault();
    24→    setError(null);
    25→
    26→    if (password.length < 6) {
    27→      setError("Password must be at least 6 characters.");
    28→      return;
    29→    }
    30→
    31→    if (password !== confirmPassword) {
    32→      setError("Passwords do not match.");
    33→      return;
    34→    }
    35→
    36→    setLoading(true);
    37→
    38→    const { error } = await supabase.auth.updateUser({ password });
    39→
    40→    if (error) {
    41→      setError(error.message);
    42→      setLoading(false);
    43→      return;
    44→    }
    45→
    46→    setSuccess(true);
    47→    setLoading(false);
    48→
    49→    setTimeout(() => {
    50→      router.push("/dashboard");
    51→      router.refresh();
    52→    }, 2000);
    53→  }
    54→
    55→  if (success) {
    56→    return (
    57→

    58→        <Card className="w-full max-w-md">
    59→          <CardHeader className="text-center">
    60→

    61→              <CheckCircle2 className="h-6 w-6 text-green-600" />
    62→

    63→            <CardTitle className="text-2xl font-bold">Password updated</CardTitle>
    64→            <CardDescription className="mt-2">
    65→              Your password has been reset. Redirecting to dashboard...
    66→            </CardDescription>
    67→          </CardHeader>
    68→        </Card>
    69→

    70→    );
    71→  }
    72→
    73→  return (
    74→

    75→      <Card className="w-full max-w-md">
    76→        <CardHeader className="text-center">
    77→          <CardTitle className="text-2xl font-bold">Set new password</CardTitle>
    78→          <CardDescription>Enter your new password below</CardDescription>
    79→        </CardHeader>
    80→        <CardContent>
    81→          <form onSubmit={handleReset} className="space-y-4">
    82→

    83→              New password
    84→              <Input
    85→                id="password"
    86→                type="password"
    87→                placeholder="At least 6 characters"
    88→                value={password}
    89→                onChange={(e) => setPassword(e.target.value)}
    90→                required
    91→                minLength={6}
    92→                autoComplete="new-password"
    93→                className="h-12 text-base"
    94→              />
    95→

    96→

    97→              Confirm password
    98→              <Input
    99→                id="confirmPassword"
   100→                type="password"
   101→                placeholder="Confirm your password"
   102→                value={confirmPassword}
   103→                onChange={(e) => setConfirmPassword(e.target.value)}
   104→                required
   105→                minLength={6}
   106→                autoComplete="new-password"
   107→                className="h-12 text-base"
   108→              />
   109→

   110→            {error && (
   111→

   112→
{error}

   113→

   114→            )}
   115→            <Button type="submit" className="w-full h-12 text-base font-semibold" disabled={loading}>
   116→              {loading ? "Updating..." : "Update password"}
   117→            </Button>
   118→          </form>
   119→

   120→            <Link href="/auth/login" className="text-primary underline hover:no-underline">
   121→              Back to login
   122→            </Link>
   123→

   124→        </CardContent>
   125→      </Card>
   126→

   127→  );
   128→}
   129→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→"use client";
     2→
     3→import { useState, useEffect } from "react";
     4→import { useRouter } from "next/navigation";
     5→import { createClient } from "@/lib/supabase/client";
     6→import { Button } from "@/components/ui/button";
     7→import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
     8→import { Mail, CheckCircle2, Clock } from "lucide-react";
     9→
    10→export default function VerifyEmailPage() {
    11→  const [emailSent, setEmailSent] = useState(false);
    12→  const [loading, setLoading] = useState(false);
    13→  const [error, setError] = useState<string | null>(null);
    14→  const router = useRouter();
    15→  const supabase = createClient();
    16→
    17→  useEffect(() => {
    18→    // Check if user is already logged in and email is verified
    19→    checkEmailStatus();
    20→  }, []);
    21→
    22→  async function checkEmailStatus() {
    23→    const { data: { user } } = await supabase.auth.getUser();
    24→
    25→    if (user?.email_confirmed_at) {
    26→      // Email is already verified, redirect to dashboard
    27→      router.push('/dashboard');
    28→    }
    29→  }
    30→
    31→  async function resendVerificationEmail() {
    32→    setLoading(true);
    33→    setError(null);
    34→
    35→    try {
    36→      const { data: { user } } = await supabase.auth.getUser();
    37→
    38→      if (!user) {
    39→        setError("No user found. Please log in again.");
    40→        setLoading(false);
    41→        return;
    42→      }
    43→
    44→      const { error } = await supabase.auth.resend({
    45→        type: 'signup',
    46→        email: user.email as string,
    47→      });
    48→
    49→      if (error) {
    50→        setError(error.message);
    51→      } else {
    52→        setEmailSent(true);
    53→      }
    54→    } catch (error) {
    55→      setError("Failed to resend verification email.");
    56→    } finally {
    57→      setLoading(false);
    58→    }
    59→  }
    60→
    61→  return (
    62→

    63→      <Card className="w-full max-w-md">
    64→        <CardHeader className="text-center">
    65→

    66→            <Mail className="h-6 w-6 text-primary" />
    67→

    68→          <CardTitle className="text-2xl font-bold">
    69→            Check your email
    70→          </CardTitle>
    71→          <CardDescription className="mt-2">
    72→            We've sent a verification email to your address. Please check your inbox and click the link to verify.
    73→          </CardDescription>
    74→        </CardHeader>
    75→        <CardContent className="space-y-4">
    76→

    77→

    78→              <Clock className="h-5 w-5 text-primary shrink-0 mt-0.5" />
    79→

    80→
Didn't receive the email?

    81→

    82→                  Check your spam folder or click the button below to resend.
    83→

    84→

    85→

    86→

    87→
    88→          {error && (
    89→

    90→
{error}

    91→

    92→          )}
    93→
    94→          {emailSent && (
    95→

    96→

    97→                <CheckCircle2 className="h-4 w-4 text-green-600 shrink-0" />
    98→

    99→                  Verification email resent. Please check your inbox.
   100→

   101→

   102→

   103→          )}
   104→
   105→

   106→            <Button
   107→              onClick={resendVerificationEmail}
   108→              disabled={loading || emailSent}
   109→              className="w-full h-12 text-base font-semibold"
   110→              variant="outline"
   111→            >
   112→              {loading ? "Sending..." : emailSent ? "Email sent" : "Resend verification email"}
   113→            </Button>
   114→
   115→            <Button
   116→              onClick={() => router.push('/auth/login')}
   117→              variant="ghost"
   118→              className="w-full h-12 text-base"
   119→            >
   120→              Back to login
   121→            </Button>
   122→

   123→        </CardContent>
   124→      </Card>
   125→

   126→  );
   127→}
   128→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Now let me read the dashboard, faq, legal, offline and authenticated pages:


1→import { redirect } from "next/navigation";
     2→import Link from "next/link";
     3→import { createClient } from "@/lib/supabase/server";
     4→import { Button } from "@/components/ui/button";
     5→import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
     6→import { Badge } from "@/components/ui/badge";
     7→import { Building2, HardHat, Plus, Users, Star } from "lucide-react";
     8→import { SignOutButton } from "@/components/sign-out-button";
     9→import { BottomNavWrapper } from "@/components/bottom-nav-wrapper";
    10→
    11→export default async function DashboardPage() {
    12→  const supabase = await createClient();
    13→
    14→  const {
    15→    data: { user },
    16→  } = await supabase.auth.getUser();
    17→
    18→  if (!user) {
    19→    redirect("/auth/login");
    20→  }
    21→
    22→  const { data: profile } = await supabase
    23→    .from("profiles")
    24→    .select("*")
    25→    .eq("id", user.id)
    26→    .single();
    27→
    28→  const isContractor = profile?.type === "contractor";
    29→
    30→  // Fetch stats
    31→  let jobCount = 0;
    32→  let matchCount = 0;
    33→  let pendingRatings: { matchId: string; otherName: string }[] = [];
    34→
    35→  if (isContractor) {
    36→    const { data: company } = await supabase
    37→      .from("companies")
    38→      .select("id")
    39→      .eq("profile_id", user.id)
    40→      .single();
    41→
    42→    if (company) {
    43→      const { count } = await supabase
    44→        .from("jobs")
    45→        .select("*", { count: "exact", head: true })
    46→        .eq("company_id", company.id)
    47→        .eq("status", "active");
    48→      jobCount = count || 0;
    49→
    50→      const { count: mCount } = await supabase
    51→        .from("matches")
    52→        .select("*, jobs!inner(company_id)", { count: "exact", head: true })
    53→        .eq("jobs.company_id", company.id)
    54→        .in("status", ["applied", "suggested"]);
    55→      matchCount = mCount || 0;
    56→    }
    57→  }
    58→
    59→  // Fetch hired matches that haven't been rated yet
    60→  const { data: hiredMatches } = await supabase
    61→    .from("matches")
    62→    .select("id, worker_id, jobs(title)")
    63→    .eq("status", "hired");
    64→
    65→  if (hiredMatches) {
    66→    for (const match of hiredMatches) {
    67→      const { data: existingRating } = await supabase
    68→        .from("ratings")
    69→        .select("id")
    70→        .eq("match_id", match.id)
    71→        .eq("from_id", user.id)
    72→        .maybeSingle();
    73→
    74→      if (!existingRating) {
    75→        const otherId = isContractor ? match.worker_id : null;
    76→        let name = "your hire";
    77→        if (otherId) {
    78→          const { data: p } = await supabase.from("profiles").select("name").eq("id", otherId).single();
    79→          if (p?.name) name = p.name;
    80→        }
    81→        pendingRatings.push({ matchId: match.id, otherName: name });
    82→      }
    83→    }
    84→  }
    85→
    86→  return (
    87→

    88→
    89→

    90→          G'day{profile?.name ? `, ${profile.name}` : ""}!
    91→

    92→

    93→          {isContractor
    94→            ? "Ready to find your next worker?"
    95→            : "Let's get you on a job."}
    96→

    97→
    98→

    99→          {/* Pending ratings prompt */}
   100→          {pendingRatings.length > 0 && (
   101→            <Card className="border-yellow-500/30 bg-yellow-500/5">
   102→              <CardHeader className="pb-3">
   103→                <CardTitle className="flex items-center gap-2 text-lg">
   104→                  <Star className="h-6 w-6 text-yellow-500" />
   105→                  Rate your experience
   106→                </CardTitle>
   107→                <CardDescription className="text-base">
   108→                  Your feedback helps build trust on RateRight
   109→                </CardDescription>
   110→              </CardHeader>
   111→              <CardContent className="space-y-2">
   112→                {pendingRatings.slice(0, 3).map((pr) => (
   113→                  <Button key={pr.matchId} asChild variant="outline" className="w-full h-12 text-base justify-start">
   114→                    <Link href={`/rate/${pr.matchId}`}>
   115→                      <Star className="h-4 w-4 mr-2 text-yellow-500" />
   116→                      Rate {pr.otherName}
   117→                    </Link>
   118→                  </Button>
   119→                ))}
   120→              </CardContent>
   121→            </Card>
   122→          )}
   123→
   124→          {isContractor ? (
   125→            <>
   126→              {/* Quick stats */}
   127→

   128→                <Card>
   129→                  <CardContent className="flex flex-col items-center p-4">
   130→                    {jobCount}
   131→                    Active Jobs
   132→                  </CardContent>
   133→                </Card>
   134→                <Card>
   135→                  <CardContent className="flex flex-col items-center p-4">
   136→                    {matchCount}
   137→                    New Matches
   138→                  </CardContent>
   139→                </Card>
   140→

   141→
   142→              {/* Post a Job CTA */}
   143→              <Card className="border-primary/30 bg-primary/5">
   144→                <CardHeader className="pb-3">
   145→                  <CardTitle className="flex items-center gap-2 text-lg">
   146→                    <Plus className="h-6 w-6" />
   147→                    Post a Job
   148→                  </CardTitle>
   149→                  <CardDescription className="text-base">
   150→                    AI writes the post. You just tap.
   151→                  </CardDescription>
   152→                </CardHeader>
   153→                <CardContent>
   154→                  <Button asChild className="w-full h-16 text-lg font-semibold">
   155→                    <Link href="/contractor/post-job">Post a Job</Link>
   156→                  </Button>
   157→                </CardContent>
   158→              </Card>
   159→
   160→              {/* View Matches */}
   161→              {matchCount > 0 && (
   162→                <Card>
   163→                  <CardHeader className="pb-3">
   164→                    <CardTitle className="flex items-center gap-2 text-lg">
   165→                      <Users className="h-6 w-6" />
   166→                      {matchCount} Worker{matchCount > 1 ? "s" : ""} Matched
   167→                    </CardTitle>
   168→                    <CardDescription className="text-base">
   169→                      Workers have applied to your jobs
   170→                    </CardDescription>
   171→                  </CardHeader>
   172→                  <CardContent>
   173→                    <Button asChild variant="outline" className="w-full h-14 text-base font-semibold">
   174→                      <Link href="/contractor/matches">View Matches</Link>
   175→                    </Button>
   176→                  </CardContent>
   177→                </Card>
   178→              )}
   179→
   180→              {/* Company profile */}
   181→              <Card>
   182→                <CardHeader className="pb-3">
   183→                  <CardTitle className="flex items-center gap-2 text-lg">
   184→                    <Building2 className="h-6 w-6" />
   185→                    Company Profile
   186→                  </CardTitle>
   187→                  <CardDescription className="text-base">
   188→                    Manage your company details
   189→                  </CardDescription>
   190→                </CardHeader>
   191→                <CardContent>
   192→                  <Button asChild variant="outline" className="w-full h-14 text-base">
   193→                    <Link href="/contractor/signup">Edit Profile</Link>
   194→                  </Button>
   195→                </CardContent>
   196→              </Card>
   197→            </>
   198→          ) : (
   199→            <>
   200→              {/* Browse Jobs CTA */}
   201→              <Card className="border-primary/30 bg-primary/5">
   202→                <CardHeader className="pb-3">
   203→                  <CardTitle className="flex items-center gap-2 text-lg">
   204→                    <HardHat className="h-6 w-6" />
   205→                    Find Work
   206→                  </CardTitle>
   207→                  <CardDescription className="text-base">
   208→                    Browse available construction jobs near you
   209→                  </CardDescription>
   210→                </CardHeader>
   211→                <CardContent>
   212→                  <Button asChild className="w-full h-16 text-lg font-semibold">
   213→                    <Link href="/worker/jobs">Browse Jobs</Link>
   214→                  </Button>
   215→                </CardContent>
   216→              </Card>
   217→
   218→              {/* Profile */}
   219→              <Card>
   220→                <CardHeader className="pb-3">
   221→                  <CardTitle className="flex items-center gap-2 text-lg">
   222→                    <HardHat className="h-6 w-6" />
   223→                    Your Profile
   224→                  </CardTitle>
   225→                  <CardDescription className="text-base">
   226→                    {profile?.onboarding_completed
   227→                      ? "View and manage your profile"
   228→                      : "A strong profile gets you more matches"}
   229→                  </CardDescription>
   230→                </CardHeader>
   231→                <CardContent>
   232→                  <Button asChild variant="outline" className="w-full h-14 text-base">
   233→                    <Link href={profile?.onboarding_completed ? "/worker/profile" : "/worker/profile/build"}>
   234→                      {profile?.onboarding_completed ? "View Profile" : "Build Profile"}
   235→                    </Link>
   236→                  </Button>
   237→                </CardContent>
   238→              </Card>
   239→            </>
   240→          )}
   241→

   242→
   243→
   244→      <BottomNavWrapper userType={profile?.type || "worker"} />
   245→

   246→  );
   247→}
   248→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→import Link from "next/link";
     2→import Image from "next/image";
     3→import type { Metadata } from "next";
     4→import { HelpCircle, Building2, Wrench, Users } from "lucide-react";
     5→import { Button } from "@/components/ui/button";
     6→import {
     7→  Accordion,
     8→  AccordionContent,
     9→  AccordionItem,
    10→  AccordionTrigger,
    11→} from "@/components/ui/accordion";
    12→
    13→export const metadata: Metadata = {
    14→  title: "FAQ — RateRight",
    15→  description:
    16→    "Frequently asked questions about RateRight, the simplest way to hire construction workers in Australia.",
    17→};
    18→
    19→export const dynamic = "force-static";
    20→
    21→const workerFaqs = [
    22→  {
    23→    q: "How does RateRight work for workers?",
    24→    a: "RateRight connects qualified construction workers with contractors who need skilled labour. Simply create your profile, verify your qualifications, and get matched with jobs that fit your skills and schedule.",
    25→  },
    26→  {
    27→    q: "Is RateRight free for workers?",
    28→    a: "Yes! It is completely free for workers to join, create a profile, and get matched with jobs. We do not charge any subscription fees or take a percentage of your earnings.",
    29→  },
    30→  {
    31→    q: "How do I get hired through RateRight?",
    32→    a: "Complete your profile with accurate information about your skills, experience, and certifications. Upload your White Card and any trade-specific licences. Contractors search our database and contact workers directly.",
    33→  },
    34→  {
    35→    q: "What trades does RateRight cover?",
    36→    a: "We cover all major construction trades including carpentry, plumbing, electrical, bricklaying, concreting, tiling, plastering, painting, landscaping, and general labour.",
    37→  },
    38→  {
    39→    q: "Do I need a White Card to join?",
    40→    a: "Yes, all workers must have a valid White Card (General Construction Induction Card) to work on Australian construction sites.",
    41→  },
    42→  {
    43→    q: "How quickly can I find work?",
    44→    a: "Many workers receive their first job invitation within 24\u201348 hours of profile approval.",
    45→  },
    46→  {
    47→    q: "How and when do I get paid?",
    48→    a: "Payment terms are agreed directly with the contractor before starting work. Most contractors pay weekly or fortnightly. RateRight does not handle payments.",
    49→  },
    50→  {
    51→    q: "Can I choose when and where I work?",
    52→    a: "Absolutely! You set your availability and preferred work locations in your profile.",
    53→  },
    54→];
    55→
    56→const contractorFaqs = [
    57→  {
    58→    q: "How does RateRight work for contractors?",
    59→    a: "RateRight gives you instant access to pre-verified construction workers. Search our database by trade, location, availability, and ratings.",
    60→  },
    61→  {
    62→    q: "What is the $50 fee about?",
    63→    a: "We charge a flat $50 fee per successful job placement. No subscriptions, no hidden costs, no percentage cuts.",
    64→  },
    65→  {
    66→    q: "How fast can I find workers?",
    67→    a: "Most contractors find suitable workers within hours. Many jobs are filled the same day they are posted.",
    68→  },
    69→  {
    70→    q: "What if the worker does not show up?",
    71→    a: "We take reliability seriously. Workers with no-shows are removed from the platform. Contact us immediately and we will help you find a replacement quickly.",
    72→  },
    73→  {
    74→    q: "Are workers verified?",
    75→    a: "Yes, all workers go through our verification process. We check White Cards, trade licences, and conduct identity verification.",
    76→  },
    77→  {
    78→    q: "How many workers can I contact?",
    79→    a: "As many as you need! There is no limit to how many workers you can view or contact.",
    80→  },
    81→  {
    82→    q: "Do I have to use RateRight for payment?",
    83→    a: "No, you handle payment directly with the worker according to your normal payroll processes.",
    84→  },
    85→  {
    86→    q: "What areas does RateRight cover?",
    87→    a: "We currently operate in Sydney, Melbourne, Brisbane, Perth, and Adelaide metropolitan areas.",
    88→  },
    89→];
    90→
    91→const generalFaqs = [
    92→  {
    93→    q: "Is RateRight a labour hire company?",
    94→    a: "No, RateRight is a marketplace platform that connects contractors directly with workers. We are not a labour hire company.",
    95→  },
    96→  {
    97→    q: "How is payment handled?",
    98→    a: "Payment is arranged directly between the contractor and worker. RateRight does not process payments or take a percentage of wages.",
    99→  },
   100→  {
   101→    q: "What areas do you cover?",
   102→    a: "RateRight currently operates in major Australian cities: Sydney, Melbourne, Brisbane, Perth, and Adelaide.",
   103→  },
   104→  {
   105→    q: "Is there a rating system?",
   106→    a: "Yes, both workers and contractors can rate each other after completing a job.",
   107→  },
   108→  {
   109→    q: "How do I get started?",
   110→    a: "Simply visit our website and click Sign Up. Workers create a profile with their skills and qualifications. Contractors can start searching immediately.",
   111→  },
   112→  {
   113→    q: "What makes RateRight different?",
   114→    a: "Unlike traditional labour hire companies, we charge contractors a simple flat fee with no ongoing subscriptions. Workers keep 100% of their wages.",
   115→  },
   116→];
   117→
   118→function FAQSection({
   119→  title,
   120→  icon,
   121→  faqs,
   122→  idPrefix,
   123→}: {
   124→  title: string;
   125→  icon: React.ReactNode;
   126→  faqs: { q: string; a: string }[];
   127→  idPrefix: string;
   128→}) {
   129→  return (
   130→

   131→

   132→

   133→          {icon}
   134→

   135→
{title}

   136→

   137→      <Accordion type="single" collapsible className="w-full">
   138→        {faqs.map((faq, i) => (
   139→          <AccordionItem key={i} value={`${idPrefix}-${i}`}>
   140→            <AccordionTrigger>{faq.q}</AccordionTrigger>
   141→            <AccordionContent>
   142→
{faq.a}

   143→            </AccordionContent>
   144→          </AccordionItem>
   145→        ))}
   146→      </Accordion>
   147→

   148→  );
   149→}
   150→
   151→export default function FAQPage() {
   152→  return (
   153→

   154→      {/* Orange accent bar */}
   155→

   156→
   157→      {/* Header */}
   158→
   159→

   160→          <Link href="/" className="flex items-center gap-2">
   161→            <Image src="/logo_black.svg" alt="RateRight" width={140} height={40} className="h-8 w-auto" priority />
   162→          </Link>
   163→          <Link href="/auth/login">
   164→            <Button variant="ghost" size="sm">
   165→              Sign in
   166→            </Button>
   167→          </Link>
   168→

   169→
   170→
   171→      {/* Hero */}
   172→

   173→

   174→

   175→            <HelpCircle className="h-6 w-6 text-primary" />
   176→

   177→

   178→            Frequently Asked Questions
   179→

   180→

   181→            Everything you need to know about hiring and finding work on
   182→            RateRight.
   183→

   184→

   185→

   186→
   187→      {/* FAQ Sections */}
   188→

   189→

   190→          <FAQSection
   191→            title="For Workers"
   192→            icon={<Wrench className="h-4 w-4 text-primary-foreground" />}
   193→            faqs={workerFaqs}
   194→            idPrefix="worker"
   195→          />
   196→
   197→          <FAQSection
   198→            title="For Contractors"
   199→            icon={<Building2 className="h-4 w-4 text-primary-foreground" />}
   200→            faqs={contractorFaqs}
   201→            idPrefix="contractor"
   202→          />
   203→
   204→          <FAQSection
   205→            title="General Questions"
   206→            icon={<Users className="h-4 w-4 text-primary-foreground" />}
   207→            faqs={generalFaqs}
   208→            idPrefix="general"
   209→          />
   210→

   211→

   212→
   213→      {/* CTA */}
   214→

   215→

   216→

   217→            Still have questions?
   218→

   219→

   220→            Get in touch and we'll get back to you as soon as we can.
   221→

   222→

   223→            <Link href="/auth/signup">
   224→              <Button className="w-full sm:w-auto h-12 gap-2 text-base font-semibold">
   225→                Get started
   226→              </Button>
   227→            </Link>
   228→

   229→

   230→

   231→
   232→      {/* Footer */}
   233→
   234→

   235→

   236→            <Image src="/logo_black.svg" alt="RateRight" width={110} height={32} className="h-6 w-auto" />
   237→

   238→

   239→            The simplest way to hire construction workers in Australia.
   240→

   241→

   242→            © {new Date().getFullYear()} RateRight Pty Ltd. All rights
   243→            reserved.
   244→

   245→

   246→
   247→

   248→  );
   249→}
   250→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→import Link from "next/link";
     2→import { ArrowLeft } from "lucide-react";
     3→
     4→export default function TermsOfServicePage() {
     5→  return (
     6→

     7→

     8→        <Link
     9→          href="/auth/signup"
    10→          className="mb-6 inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
    11→        >
    12→          <ArrowLeft className="h-4 w-4" />
    13→          Back
    14→        </Link>
    15→
    16→
Terms of Service

    17→

    18→          Last updated: February 2026
    19→

    20→
    21→

    22→

    23→
1. Acceptance of Terms

    24→

    25→              By accessing or using RateRight (“the Platform”), you agree to be bound by these Terms of
    26→              Service. If you do not agree, do not use the Platform.
    27→

    28→

    29→
    30→

    31→
2. About RateRight

    32→

    33→              RateRight is a construction hiring marketplace that connects contractors with
    34→              skilled workers. We are not a labour hire company. We provide a technology platform
    35→              to facilitate direct connections between parties.
    36→

    37→

    38→
    39→

    40→
3. User Accounts

    41→

    42→              You must provide accurate information when creating an account. You are responsible for
    43→              maintaining the security of your account credentials. You must be at least 18 years old
    44→              to use the Platform.
    45→

    46→

    47→
    48→

    49→
4. Fees

    50→

    51→              Workers can use the Platform for free. Contractors pay a flat fee of $50 AUD per
    52→              successful hire made through the Platform. Payment is processed via Stripe.
    53→

    54→

    55→
    56→

    57→
5. Worker Responsibilities

    58→

    59→              Workers must hold valid certifications (including a White Card) as required by
    60→              Australian law. Workers are responsible for ensuring their qualifications and
    61→              availability information is accurate and up to date.
    62→

    63→

    64→
    65→

    66→
6. Contractor Responsibilities

    67→

    68→              Contractors must hold a valid ABN and comply with all applicable employment laws,
    69→              including WHS obligations. The employment relationship is between the contractor
    70→              and the worker — RateRight is not a party to any employment arrangement.
    71→

    72→

    73→
    74→

    75→
7. Limitation of Liability

    76→

    77→              RateRight is provided “as is”. We do not guarantee the quality, reliability, or
    78→              suitability of any worker or contractor. To the maximum extent permitted by law,
    79→              we are not liable for any loss or damage arising from use of the Platform.
    80→

    81→

    82→
    83→

    84→
8. Termination

    85→

    86→              We may suspend or terminate your account at any time for breach of these terms
    87→              or for any other reason at our discretion.
    88→

    89→

    90→
    91→

    92→
9. Governing Law

    93→

    94→              These terms are governed by the laws of New South Wales, Australia.
    95→

    96→

    97→
    98→

    99→
10. Contact

   100→

   101→              For questions about these terms, contact us at support@rateright.com.au.
   102→

   103→

   104→

   105→

   106→

   107→  );
   108→}
   109→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→import Link from "next/link";
     2→import { ArrowLeft } from "lucide-react";
     3→
     4→export default function PrivacyPolicyPage() {
     5→  return (
     6→

     7→

     8→        <Link
     9→          href="/auth/signup"
    10→          className="mb-6 inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
    11→        >
    12→          <ArrowLeft className="h-4 w-4" />
    13→          Back
    14→        </Link>
    15→
    16→
Privacy Policy

    17→

    18→          Last updated: February 2026
    19→

    20→
    21→

    22→

    23→
1. Information We Collect

    24→
We collect information you provide when creating an account and using the Platform:

    25→

    26→
Name, email address, and phone number

    27→
ABN and company details (contractors)

    28→
Trade, experience, certifications, and availability (workers)

    29→
Location (suburb/area) for job matching

    30→
Voice recordings (if you use voice input features)

    31→
Payment information (processed by Stripe)

    32→

    33→

    34→
    35→

    36→
2. How We Use Your Information

    37→

    38→
To create and manage your account

    39→
To match workers with relevant job opportunities

    40→
To process payments for hiring fees

    41→
To generate AI-powered profiles and suggestions

    42→
To send notifications about matches and hires

    43→
To improve our services

    44→

    45→

    46→
    47→

    48→
3. AI and Voice Data

    49→

    50→              We use AI services (OpenAI) to generate profile content and transcribe voice
    51→              recordings. Voice recordings are processed in real-time and are not permanently
    52→              stored. AI-generated content is stored as part of your profile.
    53→

    54→

    55→
    56→

    57→
4. Data Sharing

    58→
We share your information with:

    59→

    60→
Other users (your profile is visible to contractors/workers on the Platform)

    61→
Stripe (for payment processing)

    62→
OpenAI (for AI features — voice transcription and profile generation)

    63→
Supabase (our database and authentication provider)

    64→

    65→
We do not sell your personal information to third parties.

    66→

    67→
    68→

    69→
5. Data Security

    70→

    71→              We use industry-standard security measures including encryption, secure
    72→              authentication, and access controls to protect your data. All data is stored
    73→              in secure cloud infrastructure.
    74→

    75→

    76→
    77→

    78→
6. Your Rights

    79→
Under the Australian Privacy Act 1988, you have the right to:

    80→

    81→
Access your personal information

    82→
Request correction of inaccurate information

    83→
Request deletion of your account and data

    84→
Opt out of marketing communications

    85→

    86→

    87→
    88→

    89→
7. Cookies

    90→

    91→              We use essential cookies for authentication and security (CSRF protection).
    92→              We do not use tracking or advertising cookies.
    93→

    94→

    95→
    96→

    97→
8. Contact

    98→

    99→              For privacy enquiries, contact us at privacy@rateright.com.au.
   100→

   101→

   102→

   103→

   104→

   105→  );
   106→}
   107→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→'use client';
     2→
     3→import Link from "next/link";
     4→import Image from "next/image";
     5→import { Button } from "@/components/ui/button";
     6→import { WifiOff, RefreshCw, Home } from "lucide-react";
     7→
     8→export default function OfflinePage() {
     9→  return (
    10→

    11→      {/* Orange accent bar */}
    12→

    13→
    14→

    15→        {/* Logo */}
    16→

    17→          <Image src="/logo_black.svg" alt="RateRight" width={160} height={46} className="h-10 w-auto" />
    18→

    19→
    20→        {/* Offline Icon */}
    21→

    22→          <WifiOff className="h-10 w-10 text-muted-foreground" />
    23→

    24→
    25→        {/* Title */}
    26→

    27→

    28→            You're offline
    29→

    30→

    31→            It looks like you've lost your internet connection. Please check your connection and try again.
    32→

    33→

    34→
    35→        {/* Actions */}
    36→

    37→          <Button
    38→            onClick={() => window.location.reload()}
    39→            className="gap-2"
    40→          >
    41→            <RefreshCw className="h-4 w-4" />
    42→            Try Again
    43→          </Button>
    44→          <Link href="/" className="sm:w-auto">
    45→            <Button variant="outline" className="gap-2 w-full">
    46→              <Home className="h-4 w-4" />
    47→              Go Home
    48→            </Button>
    49→          </Link>
    50→

    51→
    52→        {/* Additional Info */}
    53→

    54→

    55→            RateRight works best with a stable internet connection. Some features may not be available while offline.
    56→

    57→

    58→

    59→

    60→  );
    61→}

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Now let me read the worker and contractor pages:


1→import { redirect } from "next/navigation";
     2→import Link from "next/link";
     3→import { createClient } from "@/lib/supabase/server";
     4→import { Button } from "@/components/ui/button";
     5→import { Card, CardContent } from "@/components/ui/card";
     6→import { Badge } from "@/components/ui/badge";
     7→import {
     8→  HardHat,
     9→  MapPin,
    10→  Clock,
    11→  Shield,
    12→  Zap,
    13→  Edit3,
    14→  Wrench,
    15→  Calendar,
    16→  Sparkles,
    17→  Camera,
    18→} from "lucide-react";
    19→import { BottomNavWrapper } from "@/components/bottom-nav-wrapper";
    20→import { AvatarUpload } from "@/components/avatar-upload";
    21→
    22→export default async function WorkerProfilePage() {
    23→  const supabase = await createClient();
    24→
    25→  const {
    26→    data: { user },
    27→  } = await supabase.auth.getUser();
    28→
    29→  if (!user) {
    30→    redirect("/auth/login");
    31→  }
    32→
    33→  const { data: profile } = await supabase
    34→    .from("profiles")
    35→    .select("*")
    36→    .eq("id", user.id)
    37→    .single();
    38→
    39→  // If onboarding not completed, send to build
    40→  if (!profile?.onboarding_completed) {
    41→    redirect("/worker/profile/build");
    42→  }
    43→
    44→  const { data: workerProfile } = await supabase
    45→    .from("worker_profiles")
    46→    .select("*")
    47→    .eq("profile_id", user.id)
    48→    .single();
    49→
    50→  if (!workerProfile) {
    51→    redirect("/worker/profile/build");
    52→  }
    53→
    54→  const trades = workerProfile.trades || [];
    55→  const skills = (workerProfile.ai_extracted as { skills?: string[] })?.skills || [];
    56→  const certs = workerProfile.certifications || [];
    57→  const expLabel = getExperienceLabel(workerProfile.experience_years);
    58→
    59→  // Fetch ratings
    60→  const { data: ratings } = await supabase
    61→    .from("ratings")
    62→    .select("score")
    63→    .eq("to_id", user.id);
    64→
    65→  const avgRating = ratings && ratings.length > 0
    66→    ? (ratings.reduce((sum, r) => sum + r.score, 0) / ratings.length).toFixed(1)
    67→    : null;
    68→
    69→  return (
    70→

    71→
    72→        {/* Profile header */}
    73→

    74→          <AvatarUpload
    75→            currentUrl={profile.avatar_url}
    76→            userName={profile.name || user.email || ""}
    77→          />
    78→
    79→
{profile.name || "Worker"}

    80→
    81→

    82→            {trades.map((t: string) => (
    83→              <Badge key={t} variant="secondary" className="text-sm">
    84→                <Wrench className="mr-1 h-3 w-3" />
    85→                {t}
    86→              </Badge>
    87→            ))}
    88→

    89→
    90→

    91→            {profile.suburb && (
    92→
    93→                <MapPin className="h-3.5 w-3.5" />
    94→                {profile.suburb}
    95→
    96→            )}
    97→            {expLabel && (
    98→
    99→                <Clock className="h-3.5 w-3.5" />
   100→                {expLabel}
   101→
   102→            )}
   103→            {avgRating && (
   104→
   105→                ⭐ {avgRating} ({ratings!.length})
   106→
   107→            )}
   108→

   109→
   110→          {workerProfile.availability && (
   111→            <Badge variant="outline" className="mt-2">
   112→              <Calendar className="mr-1 h-3 w-3" />
   113→              {workerProfile.availability}
   114→            </Badge>
   115→          )}
   116→

   117→
   118→        {/* Bio */}
   119→        {workerProfile.bio && (
   120→          <Card className="mt-6">
   121→            <CardContent className="pt-5">
   122→

   123→                <Sparkles className="h-4 w-4" />
   124→                About me
   125→

   126→
{workerProfile.bio}

   127→            </CardContent>
   128→          </Card>
   129→        )}
   130→
   131→        {/* Skills */}
   132→        {skills.length > 0 && (
   133→          <Card className="mt-3">
   134→            <CardContent className="pt-5">
   135→

   136→                <Zap className="h-4 w-4" />
   137→                Skills
   138→

   139→

   140→                {skills.map((skill: string) => (
   141→                  <Badge key={skill} className="text-sm">
   142→                    {skill}
   143→                  </Badge>
   144→                ))}
   145→

   146→            </CardContent>
   147→          </Card>
   148→        )}
   149→
   150→        {/* Certifications */}
   151→        {certs.length > 0 && (
   152→          <Card className="mt-3">
   153→            <CardContent className="pt-5">
   154→

   155→                <Shield className="h-4 w-4" />
   156→                Certifications
   157→

   158→

   159→                {certs.map((cert: string) => (
   160→

   164→                    <Shield className="h-4 w-4 text-primary" />
   165→                    {cert}
   166→

   167→                ))}
   168→

   169→            </CardContent>
   170→          </Card>
   171→        )}
   172→
   173→        {/* Edit button */}
   174→

   175→          <Button asChild variant="outline" className="w-full h-14 text-base gap-2">
   176→            <Link href="/worker/profile/build">
   177→              <Edit3 className="h-5 w-5" />
   178→              Edit Profile
   179→            </Link>
   180→          </Button>
   181→

   182→
   183→
   184→      <BottomNavWrapper userType="worker" />
   185→

   186→  );
   187→}
   188→
   189→function getExperienceLabel(years: number | null): string | null {
   190→  if (years === null || years === undefined) return null;
   191→  if (years === 0) return "< 1 year";
   192→  if (years <= 3) return `${years} years`;
   193→  if (years <= 5) return "3-5 years";
   194→  if (years <= 10) return "5-10 years";
   195→  return "10+ years";
   196→}
   197→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>