feat: Transform HookLab to OBC Maçonnerie showcase site
Complete transformation of the Next.js project into a professional showcase site for OBC Maçonnerie (Benoît Colin, maçon in Nord 59). Key changes: - Remove all HookLab/Sanity/Supabase/Stripe/admin/training infrastructure - Full OBC Maçonnerie identity: logo, colors, contact info, SIREN - Schema.org LocalBusiness structured data for Benoît Colin - SEO metadata for all pages targeting Nord 59 keywords New pages created (23 total): - Home page with 10 sections (hero, services, pillars, partners, zone, realisations, testimonials, FAQ, contact form, footer) - Service pages: construction-maison, renovation, assainissement, creation-acces, demolition, services - Secondary pages: realisations, partenaires, contact - Blog: listing + 6 SEO articles with static content - 8 local SEO pages: Orchies, Douai, Valenciennes, Mouchin, Flines-lès-Raches, Saint-Amand-les-Eaux - Legal pages: mentions-legales, cgv, confidentialite (OBC adapted) Components: - Navbar with OBC branding + mobile menu - Footer with dark navy theme, services + navigation links - ContactForm client component (devis request) - LocalSEOPage reusable component for local SEO pages - CookieBanner updated with OBC cookie key Config: - layout.tsx: OBC metadata, Schema.org, no Sanity CDN - globals.css: stone color variables added - next.config.ts: removed Sanity CDN remotePatterns - sitemap.ts: all 30 OBC pages - robots.ts: allow all except /api/ - api/contact/route.ts: OBC devis email template https://claude.ai/code/session_01Uec4iHjcPwB1pU41idWEdF
This commit is contained in:
@@ -1,218 +0,0 @@
|
||||
// Types pour la base de données Supabase
|
||||
export type Database = {
|
||||
public: {
|
||||
Tables: {
|
||||
profiles: {
|
||||
Row: {
|
||||
id: string;
|
||||
email: string;
|
||||
full_name: string | null;
|
||||
persona: "jeune" | "parent" | null;
|
||||
stripe_customer_id: string | null;
|
||||
subscription_status: "inactive" | "active" | "cancelled" | "paused";
|
||||
subscription_tier: "coaching" | "suivi" | null;
|
||||
subscription_end_date: string | null;
|
||||
is_admin: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
Insert: {
|
||||
id: string;
|
||||
email: string;
|
||||
full_name?: string | null;
|
||||
persona?: "jeune" | "parent" | null;
|
||||
stripe_customer_id?: string | null;
|
||||
subscription_status?: "inactive" | "active" | "cancelled" | "paused";
|
||||
subscription_tier?: "coaching" | "suivi" | null;
|
||||
subscription_end_date?: string | null;
|
||||
is_admin?: boolean;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
};
|
||||
Update: {
|
||||
id?: string;
|
||||
email?: string;
|
||||
full_name?: string | null;
|
||||
persona?: "jeune" | "parent" | null;
|
||||
stripe_customer_id?: string | null;
|
||||
subscription_status?: "inactive" | "active" | "cancelled" | "paused";
|
||||
subscription_tier?: "coaching" | "suivi" | null;
|
||||
subscription_end_date?: string | null;
|
||||
is_admin?: boolean;
|
||||
updated_at?: string;
|
||||
};
|
||||
};
|
||||
candidatures: {
|
||||
Row: {
|
||||
id: string;
|
||||
email: string;
|
||||
firstname: string;
|
||||
phone: string;
|
||||
persona: string;
|
||||
age: number;
|
||||
experience: string;
|
||||
time_daily: string;
|
||||
availability: string;
|
||||
start_date: string;
|
||||
motivation: string;
|
||||
monthly_goal: string;
|
||||
biggest_fear: string;
|
||||
tiktok_username: string | null;
|
||||
status: "pending" | "approved" | "rejected";
|
||||
created_at: string;
|
||||
};
|
||||
Insert: {
|
||||
id?: string;
|
||||
email: string;
|
||||
firstname: string;
|
||||
phone: string;
|
||||
persona: string;
|
||||
age: number;
|
||||
experience: string;
|
||||
time_daily: string;
|
||||
availability: string;
|
||||
start_date: string;
|
||||
motivation: string;
|
||||
monthly_goal: string;
|
||||
biggest_fear: string;
|
||||
tiktok_username?: string | null;
|
||||
status?: "pending" | "approved" | "rejected";
|
||||
created_at?: string;
|
||||
};
|
||||
Update: {
|
||||
email?: string;
|
||||
firstname?: string;
|
||||
phone?: string;
|
||||
persona?: string;
|
||||
age?: number;
|
||||
experience?: string;
|
||||
time_daily?: string;
|
||||
availability?: string;
|
||||
start_date?: string;
|
||||
motivation?: string;
|
||||
monthly_goal?: string;
|
||||
biggest_fear?: string;
|
||||
tiktok_username?: string | null;
|
||||
status?: "pending" | "approved" | "rejected";
|
||||
};
|
||||
};
|
||||
modules: {
|
||||
Row: {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string | null;
|
||||
week_number: number;
|
||||
order_index: number;
|
||||
content_type: "video" | "pdf" | "text" | "quiz" | null;
|
||||
content_url: string | null;
|
||||
duration_minutes: number | null;
|
||||
is_published: boolean;
|
||||
created_at: string;
|
||||
};
|
||||
Insert: {
|
||||
id?: string;
|
||||
title: string;
|
||||
description?: string | null;
|
||||
week_number: number;
|
||||
order_index: number;
|
||||
content_type?: "video" | "pdf" | "text" | "quiz" | null;
|
||||
content_url?: string | null;
|
||||
duration_minutes?: number | null;
|
||||
is_published?: boolean;
|
||||
created_at?: string;
|
||||
};
|
||||
Update: {
|
||||
title?: string;
|
||||
description?: string | null;
|
||||
week_number?: number;
|
||||
order_index?: number;
|
||||
content_type?: "video" | "pdf" | "text" | "quiz" | null;
|
||||
content_url?: string | null;
|
||||
duration_minutes?: number | null;
|
||||
is_published?: boolean;
|
||||
};
|
||||
};
|
||||
user_progress: {
|
||||
Row: {
|
||||
id: string;
|
||||
user_id: string;
|
||||
module_id: string;
|
||||
completed: boolean;
|
||||
completed_at: string | null;
|
||||
notes: string | null;
|
||||
created_at: string;
|
||||
};
|
||||
Insert: {
|
||||
id?: string;
|
||||
user_id: string;
|
||||
module_id: string;
|
||||
completed?: boolean;
|
||||
completed_at?: string | null;
|
||||
notes?: string | null;
|
||||
created_at?: string;
|
||||
};
|
||||
Update: {
|
||||
completed?: boolean;
|
||||
completed_at?: string | null;
|
||||
notes?: string | null;
|
||||
};
|
||||
};
|
||||
payments: {
|
||||
Row: {
|
||||
id: string;
|
||||
user_id: string;
|
||||
stripe_payment_intent_id: string;
|
||||
amount: number;
|
||||
currency: string;
|
||||
status: string;
|
||||
metadata: Record<string, unknown> | null;
|
||||
created_at: string;
|
||||
};
|
||||
Insert: {
|
||||
id?: string;
|
||||
user_id: string;
|
||||
stripe_payment_intent_id: string;
|
||||
amount: number;
|
||||
currency?: string;
|
||||
status: string;
|
||||
metadata?: Record<string, unknown> | null;
|
||||
created_at?: string;
|
||||
};
|
||||
Update: {
|
||||
status?: string;
|
||||
metadata?: Record<string, unknown> | null;
|
||||
};
|
||||
};
|
||||
site_images: {
|
||||
Row: {
|
||||
key: string;
|
||||
url: string;
|
||||
label: string | null;
|
||||
updated_at: string;
|
||||
};
|
||||
Insert: {
|
||||
key: string;
|
||||
url: string;
|
||||
label?: string | null;
|
||||
updated_at?: string;
|
||||
};
|
||||
Update: {
|
||||
key?: string;
|
||||
url?: string;
|
||||
label?: string | null;
|
||||
updated_at?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// Types helpers
|
||||
export type Profile = Database["public"]["Tables"]["profiles"]["Row"];
|
||||
export type Candidature = Database["public"]["Tables"]["candidatures"]["Row"];
|
||||
export type CandidatureInsert = Database["public"]["Tables"]["candidatures"]["Insert"];
|
||||
export type Module = Database["public"]["Tables"]["modules"]["Row"];
|
||||
export type UserProgress = Database["public"]["Tables"]["user_progress"]["Row"];
|
||||
export type Payment = Database["public"]["Tables"]["payments"]["Row"];
|
||||
export type ModuleInsert = Database["public"]["Tables"]["modules"]["Insert"];
|
||||
export type ModuleUpdate = Database["public"]["Tables"]["modules"]["Update"];
|
||||
Reference in New Issue
Block a user