Skip to main content

Components Documentation

Component Categories

  1. UI Components - Base shadcn/ui components
  2. Form Components - Input and form elements
  3. Feedback Components - Notifications and alerts
  4. Layout Components - Page structure
  5. Sidebar Components - Navigation
  6. Blockchain Components - Blockchain UI
  7. Chart Components - Data visualization
  8. Auth Components - Authentication forms
  9. Animation Components - Motion and animation effects
  10. Home Components - Landing page components
  11. Water Recovery Components - Water recovery calculations

UI Components

Base components from shadcn/ui library. Located in src/components/ui/.

Button

// src/components/ui/button.tsx
import { Button } from "@/components/ui/button";

<Button variant="default">Default</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Destructive</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
<Button disabled>Disabled</Button>

Variants: default, destructive, outline, secondary, ghost, link Sizes: default, sm, lg, icon

Card

// src/components/ui/card.tsx
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "@/components/ui/card";

<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Description</CardDescription>
</CardHeader>
<CardContent>Content</CardContent>
<CardFooter>Footer</CardFooter>
</Card>;

Input

// src/components/ui/input.tsx
import { Input } from "@/components/ui/input";

<Input type="text" placeholder="Enter value" />
<Input type="number" step="0.1" />
<Input disabled />

Select

// src/components/ui/select.tsx
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@/components/ui/select";

<Select value={value} onValueChange={setValue}>
<SelectTrigger>
<SelectValue placeholder="Select..." />
</SelectTrigger>
<SelectContent>
<SelectItem value="opt1">Option 1</SelectItem>
<SelectItem value="opt2">Option 2</SelectItem>
</SelectContent>
</Select>;

Table

// src/components/ui/table.tsx
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/ui/table";

<Table>
<TableHeader>
<TableRow>
<TableHead>Column 1</TableHead>
<TableHead>Column 2</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Data 1</TableCell>
<TableCell>Data 2</TableCell>
</TableRow>
</TableBody>
</Table>;

Badge

// src/components/ui/badge.tsx
import { Badge } from "@/components/ui/badge";

<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Error</Badge>
<Badge variant="outline">Outline</Badge>

Tooltip

// src/components/ui/tooltip.tsx
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@/components/ui/tooltip";

<TooltipProvider>
<Tooltip>
<TooltipTrigger>Hover me</TooltipTrigger>
<TooltipContent>Tooltip text</TooltipContent>
</Tooltip>
</TooltipProvider>;

Skeleton

// src/components/ui/skeleton.tsx
import { Skeleton } from "@/components/ui/skeleton";

<Skeleton className="h-4 w-[200px]" />
<Skeleton className="h-12 w-12 rounded-full" />

Spinner

// src/components/ui/spinner.tsx
import { Spinner } from "@/components/ui/spinner";

<Spinner />
<Spinner className="w-8 h-8" />

Avatar

// src/components/ui/avatar.tsx
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";

<Avatar>
<AvatarImage src={photoUrl} alt="User" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>;

Separator

// src/components/ui/separator.tsx
import { Separator } from "@/components/ui/separator";

<Separator />
<Separator orientation="vertical" />
// src/components/ui/breadcrumb.tsx
import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";

<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Current</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>;

Form Components

Custom form components located in src/components/forms/.

InputField

Styled input with label.

// src/components/forms/input-field.tsx
import { InputField } from "@/components/forms";

interface InputFieldProps {
label: string;
name: string;
value: string | number;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
placeholder?: string;
type?: string;
required?: boolean;
}

<InputField label="Flow Rate" name="flow_rate" value={formData.flow_rate} onChange={handleChange} placeholder="150" />;

SelectField

Styled select with label.

// src/components/forms/select-field.tsx
import { SelectField } from "@/components/forms";

interface SelectFieldProps {
label: string;
value: string;
onValueChange: (value: string) => void;
options: Array<{ value: string; label: string }>;
placeholder?: string;
}

<SelectField
label="Use Case"
value={useCase}
onValueChange={setUseCase}
options={[
{ value: "irrigation", label: "Irrigation" },
{ value: "domestic", label: "Domestic Use" },
]}
/>;

StatusBadge

Status indicator badge with color coding.

// src/components/forms/status-badge.tsx
import { StatusBadge } from "@/components/forms";

interface StatusBadgeProps {
status: string; // "PASS", "FAIL", "UNKNOWN", "Good", "Moderate", "Poor"
}

<StatusBadge status="PASS" /> // Green
<StatusBadge status="FAIL" /> // Red
<StatusBadge status="Good" /> // Green
<StatusBadge status="Poor" /> // Red

Feedback Components

Located in src/components/feedback/.

Toaster

Toast notification container.

// src/components/feedback/toaster.tsx
import { Toaster } from "@/components/feedback";

interface Toast {
id: string;
title: string;
description?: string;
variant?: "default" | "success" | "destructive";
}

// In component
const { toast, toasts, dismiss } = useToast();

<Toaster toasts={toasts} dismiss={dismiss} />;

// Trigger toast
toast({
title: "Success",
description: "Report saved",
variant: "success",
});

Layout Components

Located in src/components/layout/.

Standard page header and footer components.

import { Header, Footer } from "@/components/layout";

<Header />
<main>{children}</main>
<Footer />

Located in src/components/sidebar/.

AppSidebar

Main application sidebar with navigation.

// src/components/sidebar/app-sidebar.tsx
import { AppSidebar } from "@/components/sidebar/app-sidebar";

// Uses SidebarProvider context
<SidebarProvider>
<AppSidebar />
<SidebarInset>{/* Page content */}</SidebarInset>
</SidebarProvider>;

Main navigation items with optional sub-items.

// src/components/sidebar/nav-main.tsx
import { NavMain } from "@/components/sidebar/nav-main";

const navItems = [
{
title: "Dashboard",
url: "/dashboard",
icon: LayoutDashboard,
isActive: true,
},
{
title: "Models",
url: "#",
icon: Bot,
items: [
{ title: "Prediction", url: "/prediction-model" },
{ title: "Treatment", url: "/treatment-model" },
],
},
];

<NavMain items={navItems} />;

User profile dropdown in sidebar footer.

// src/components/sidebar/nav-user.tsx
import { NavUser } from "@/components/sidebar/nav-user";

<NavUser
user={{
name: "John Doe",
email: "john@example.com",
avatar: "/avatar.jpg",
}}
/>;

Blockchain Components

Located in src/components/blockchain/.

BlockchainStatus

Dashboard widget showing blockchain connection status.

// src/components/blockchain/blockchain-status.tsx
import { BlockchainStatus } from "@/components/blockchain";

<BlockchainStatus />;

// Displays:
// - Chain name (Polygon Amoy)
// - Connection status
// - Wallet balance
// - Total reports stored

BlockchainBadge

Inline badge showing blockchain verification status.

// src/components/blockchain/blockchain-badge.tsx
import { BlockchainBadge } from "@/components/blockchain";

<BlockchainBadge verified={true} explorerUrl="https://amoy.polygonscan.com/tx/..." transactionHash="0x..." />;

VerifyDialog

Modal for verifying report hash on blockchain.

// src/components/blockchain/verify-dialog.tsx
import { VerifyDialog } from "@/components/blockchain";

<VerifyDialog reportHash="0xabc..." onVerify={handleVerify} isVerifying={isLoading} result={verificationResult} />;

Chart Components

Located in src/components/charts/.

QualityChart

Water quality visualization chart.

// src/components/charts/quality-chart.tsx
import { QualityChart } from "@/components/charts";

<QualityChart
data={[
{ parameter: "BOD", value: 20, limit: 30 },
{ parameter: "COD", value: 150, limit: 250 },
]}
/>;

Auth Components

Located in src/components/auth/.

SignInForm

Login form with email/password and Google OAuth.

// src/components/auth/sign-in-form.tsx
import { SignInForm } from "@/components/auth/sign-in-form";

<SignInForm />;

// Handles:
// - Email/password validation
// - Google sign-in button
// - Error display
// - Redirect after success

SignUpForm

Registration form.

// src/components/auth/sign-up-form.tsx
import { SignUpForm } from "@/components/auth/sign-up-form";

<SignUpForm />;

// Handles:
// - Name, email, password fields
// - Password confirmation
// - Validation
// - Account creation

Animation Components

Located in src/components/animation/. Advanced animation components using Motion (Framer Motion).

BlurInView

Animates children with blur and fade effect when scrolling into view.

// src/components/animation/blur-in-view.tsx
import { BlurInView } from "@/components/animation/blur-in-view";

<BlurInView delay={0.2} direction="up">
<Card>Content appears with blur animation</Card>
</BlurInView>

Props:

  • delay?: number - Animation delay in seconds
  • direction?: "up" | "down" | "left" | "right" - Direction of entrance
  • className?: string - Additional classes

BlurText

Animated text with per-word or per-character blur effects.

// src/components/animation/blur-text.tsx
import { BlurText } from "@/components/animation/blur-text";

<BlurText
text="Animated Heading Text"
className="text-4xl font-bold"
animateBy="words"
delay={80}
/>

Props:

  • text: string - Text to animate
  • animateBy?: "words" | "characters" - Animation granularity
  • delay?: number - Delay between each word/character
  • className?: string - Text styling classes

Magnet3DCard

3D hover effect card with magnetic cursor following.

// src/components/animation/magnet-3d-card.tsx
import { Magnet3DCard } from "@/components/animation/magnet-3d-card";

<Magnet3DCard className="h-full">
<div className="p-6">Card content with 3D hover</div>
</Magnet3DCard>

InfiniteMarquee

Continuous scrolling content marquee.

// src/components/animation/infinite-marquee.tsx
import { InfiniteMarquee } from "@/components/animation/infinite-marquee";

<InfiniteMarquee speed={50} direction="left">
{items.map(item => <MarqueeItem key={item.id} {...item} />)}
</InfiniteMarquee>

GlassSurface

Glassmorphism effect surface with blur backdrop.

// src/components/animation/glass-surface.tsx
import { GlassSurface } from "@/components/animation/glass-surface";

<GlassSurface blur={10} opacity={0.5}>
<div>Content on glass surface</div>
</GlassSurface>

FuzzyText

Text with fuzzy/glitch effect on hover.

// src/components/animation/fuzzy-text.tsx
import { FuzzyText } from "@/components/animation/fuzzy-text";

<FuzzyText text="Hover for effect" className="text-2xl" />

ProximityText

Text that reacts to cursor proximity.

// src/components/animation/proximity-text.tsx
import { ProximityText } from "@/components/animation/proximity-text";

<ProximityText text="Interactive Text" radius={100} />

HoverFollowComponent / HoverFollowImage

Components that follow cursor movement.

// src/components/animation/hover-follow-component.tsx
import { HoverFollowComponent } from "@/components/animation/hover-follow-component";

<HoverFollowComponent intensity={20}>
<Image src="/hero.png" alt="Hero" />
</HoverFollowComponent>

Home Components

Located in src/components/home/. Components specific to the landing page.

WaterWebGL

WebGL-based water simulation background.

// src/components/home/water-webgl.tsx
import { WaterWebGL } from "@/components/home/water-webgl";

<WaterWebGL color="#1a3cff" opacity={0.5} />

Props:

  • color?: string - Water tint color
  • opacity?: number - Water opacity (0-1)

Background

Animated background patterns for landing sections.

// src/components/home/background.tsx
import { Background } from "@/components/home/background";

<Background variant="dots" />
<Background variant="grid" />

HeroText

Animated hero section text with typing effect.

// src/components/home/hero-text.tsx
import { HeroText } from "@/components/home/hero-text";

<HeroText
headline="Transform Wastewater"
subheadline="Into valuable resources"
/>

Timeline

Visual timeline component for process display.

// src/components/home/timeline.tsx
import { Timeline } from "@/components/home/timeline";

<Timeline items={processSteps} />

DropletScene

3D droplet animation scene (Three.js).

// src/components/home/droplet-scene.tsx
import { DropletScene } from "@/components/home/droplet-scene";

<DropletScene />

Water Recovery Components

Located in src/components/water-recovery/. Components for water recovery calculations.

WaterRecoveryCard

Interactive card for calculating water recovery potential.

// src/components/water-recovery/WaterRecoveryCard.tsx
import { WaterRecoveryCard } from "@/components/water-recovery/WaterRecoveryCard";

<WaterRecoveryCard
treatmentStage="Secondary"
qualityScore={85}
className="w-full"
/>

Props:

  • treatmentStage: string - Current treatment stage
  • qualityScore?: number - Water quality score (0-100)
  • className?: string - Additional classes

Features:

  • Preset volume selection
  • Custom volume input
  • Recovery percentage calculation
  • Potential use cases display
  • Environmental impact metrics

Component Best Practices

Import Pattern

// Prefer barrel imports
import { Button, Card, Input } from "@/components/ui";
import { InputField, StatusBadge } from "@/components/forms";
import { BlurInView, Magnet3DCard } from "@/components/animation";

Props Pattern

// Use interface for complex props
interface ComponentProps {
required: string;
optional?: number;
callback: (value: string) => void;
}

// Spread remaining props
function Component({ required, optional, ...props }: ComponentProps) {
return <div {...props}>{required}</div>;
}

Styling Pattern

// Use cn() for conditional classes
import { cn } from "@/lib/utils";

<div
className={cn(
"base-classes",
condition && "conditional-classes",
className // Allow override
)}
/>;

Animation Pattern

// Wrap content in animation components for effects
<BlurInView delay={0.1}>
<Magnet3DCard>
<Card>
<CardContent>Enhanced card with animations</CardContent>
</Card>
</Magnet3DCard>
</BlurInView>

Last Updated: December 2024