Sets up the foundational structure for the CAR Auto Center application using Vite and React. Includes project dependencies, basic HTML structure, TypeScript configuration, and initial README content. This commit establishes the project's build tool, core libraries, and essential configuration files.
123 lines
4.2 KiB
TypeScript
123 lines
4.2 KiB
TypeScript
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
import {
|
|
PROMISES, SERVICES, PACKAGES, SPECIAL_OFFERS,
|
|
GALLERY_IMAGES, STATS, WHY_CHOOSE_ITEMS, TESTIMONIALS,
|
|
TEAM, FAQS, BLOG_POSTS, DEFAULT_SETTINGS, DEFAULT_VISIBILITY, CLIENT_LOGOS, DEFAULT_TEXTS,
|
|
DEFAULT_HEADER, DEFAULT_FOOTER, BEFORE_AFTER_ITEMS
|
|
} from '../data';
|
|
import { supabase, isSupabaseConfigured } from '../lib/supabase';
|
|
import { GlobalSettings, SectionVisibility, SectionTexts, HeaderConfig, FooterConfig, BeforeAfterItem } from '../types';
|
|
|
|
// Estado inicial combina todos os dados
|
|
const INITIAL_DATA = {
|
|
settings: DEFAULT_SETTINGS,
|
|
visibility: DEFAULT_VISIBILITY,
|
|
hero: {
|
|
title: "Manutenção e Reparos <span class='text-primary'>Automotivos</span>",
|
|
subtitle: "24h de atendimento • Especialistas em todas as marcas • Garantia em todos os serviços.",
|
|
bgImage: "https://images.unsplash.com/photo-1625047509168-a7026f36de04?auto=format&fit=crop&q=80&w=1920",
|
|
buttonText: "Agendar Agora"
|
|
},
|
|
texts: DEFAULT_TEXTS, // Novos textos
|
|
header: DEFAULT_HEADER, // Config do Menu
|
|
footer: DEFAULT_FOOTER, // Config do Rodapé
|
|
promises: PROMISES,
|
|
services: SERVICES,
|
|
packages: PACKAGES,
|
|
specialOffers: SPECIAL_OFFERS,
|
|
gallery: GALLERY_IMAGES,
|
|
beforeAfter: BEFORE_AFTER_ITEMS, // Nova seção
|
|
stats: STATS,
|
|
whyChoose: WHY_CHOOSE_ITEMS,
|
|
testimonials: TESTIMONIALS,
|
|
team: TEAM,
|
|
faqs: FAQS,
|
|
blog: BLOG_POSTS,
|
|
clients: CLIENT_LOGOS
|
|
};
|
|
|
|
type DataType = typeof INITIAL_DATA;
|
|
|
|
interface DataContextType {
|
|
data: DataType;
|
|
updateData: (section: keyof DataType, newData: any) => Promise<void>;
|
|
isLoading: boolean;
|
|
getWhatsAppLink: (message?: string) => string;
|
|
}
|
|
|
|
const DataContext = createContext<DataContextType | undefined>(undefined);
|
|
|
|
export const DataProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
const [data, setData] = useState<DataType>(INITIAL_DATA);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
// Carregar dados ao iniciar
|
|
useEffect(() => {
|
|
loadData();
|
|
}, []);
|
|
|
|
const loadData = async () => {
|
|
try {
|
|
if (isSupabaseConfigured()) {
|
|
const { data: dbData, error } = await supabase.from('site_content').select('*').single();
|
|
if (dbData && !error) {
|
|
// Merge with initial data to ensure new fields are present if DB is old
|
|
setData(prev => ({
|
|
...INITIAL_DATA,
|
|
...dbData.content,
|
|
texts: { ...INITIAL_DATA.texts, ...dbData.content.texts },
|
|
header: { ...INITIAL_DATA.header, ...dbData.content.header },
|
|
footer: { ...INITIAL_DATA.footer, ...dbData.content.footer }
|
|
}));
|
|
}
|
|
} else {
|
|
const localData = localStorage.getItem('car_site_data');
|
|
if (localData) {
|
|
const parsedData = JSON.parse(localData);
|
|
setData(prev => ({
|
|
...INITIAL_DATA,
|
|
...parsedData,
|
|
texts: { ...INITIAL_DATA.texts, ...parsedData.texts },
|
|
header: { ...INITIAL_DATA.header, ...parsedData.header },
|
|
footer: { ...INITIAL_DATA.footer, ...parsedData.footer }
|
|
}));
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error("Erro ao carregar dados", error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
const updateData = async (section: keyof DataType, newData: any) => {
|
|
const updatedFullData = { ...data, [section]: newData };
|
|
setData(updatedFullData);
|
|
|
|
if (isSupabaseConfigured()) {
|
|
await supabase.from('site_content').upsert({ id: 1, content: updatedFullData });
|
|
} else {
|
|
localStorage.setItem('car_site_data', JSON.stringify(updatedFullData));
|
|
}
|
|
};
|
|
|
|
const getWhatsAppLink = (message: string = '') => {
|
|
const phone = data.settings.whatsappNumber.replace(/\D/g, '');
|
|
const encodedMessage = encodeURIComponent(message);
|
|
return `https://wa.me/${phone}?text=${encodedMessage}`;
|
|
};
|
|
|
|
return (
|
|
<DataContext.Provider value={{ data, updateData, isLoading, getWhatsAppLink }}>
|
|
{children}
|
|
</DataContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useData = () => {
|
|
const context = useContext(DataContext);
|
|
if (context === undefined) {
|
|
throw new Error('useData must be used within a DataProvider');
|
|
}
|
|
return context;
|
|
}; |