Files
obc-terrassement/components/ui/Input.tsx
Claude 41e686c560 feat: complete HookLab MVP - TikTok Shop coaching platform
Full-stack Next.js 15 application with:
- Landing page with marketing components (Hero, Testimonials, Pricing, FAQ)
- Multi-step candidature form with API route
- Stripe Checkout integration (subscription + webhooks)
- Supabase Auth (login/register) with middleware protection
- Dashboard with progress tracking and module system
- Formations pages with completion tracking
- Profile management with password change
- Database schema with RLS policies
- Resend email integration for transactional emails

Stack: Next.js 15, TypeScript, Tailwind CSS v4, Supabase, Stripe, Resend

https://claude.ai/code/session_01H2aRGDaKgarPvhay2HxN6Y
2026-02-08 12:39:18 +00:00

78 lines
2.2 KiB
TypeScript

"use client";
import { cn } from "@/lib/utils";
import { InputHTMLAttributes, TextareaHTMLAttributes, forwardRef } from "react";
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
const Input = forwardRef<HTMLInputElement, InputProps>(
({ className, label, error, id, ...props }, ref) => {
return (
<div className="space-y-1.5">
{label && (
<label
htmlFor={id}
className="block text-sm font-medium text-white/80"
>
{label}
</label>
)}
<input
ref={ref}
id={id}
className={cn(
"w-full px-4 py-3 bg-dark-lighter border border-dark-border rounded-[12px] text-white placeholder:text-white/30 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors",
error && "border-error focus:border-error focus:ring-error",
className
)}
{...props}
/>
{error && <p className="text-sm text-error">{error}</p>}
</div>
);
}
);
Input.displayName = "Input";
// Textarea séparé
interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
label?: string;
error?: string;
}
const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, label, error, id, ...props }, ref) => {
return (
<div className="space-y-1.5">
{label && (
<label
htmlFor={id}
className="block text-sm font-medium text-white/80"
>
{label}
</label>
)}
<textarea
ref={ref}
id={id}
className={cn(
"w-full px-4 py-3 bg-dark-lighter border border-dark-border rounded-[12px] text-white placeholder:text-white/30 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-colors resize-none",
error && "border-error focus:border-error focus:ring-error",
className
)}
{...props}
/>
{error && <p className="text-sm text-error">{error}</p>}
</div>
);
}
);
Textarea.displayName = "Textarea";
export { Input as default, Textarea };