Initial commit: CMS completo com gerenciamento de leads e personalização de tema

This commit is contained in:
Erik
2025-11-26 14:09:21 -03:00
commit aaa1709e41
106 changed files with 26268 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
"use client";
import { useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
export default function NewProject() {
const router = useRouter();
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState({
title: '',
category: '',
client: '',
status: 'active',
description: '',
date: ''
});
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
// Simulate API call
setTimeout(() => {
console.log('Project data:', formData);
setLoading(false);
router.push('/admin/projetos');
}, 1500);
};
return (
<div className="max-w-4xl mx-auto">
<div className="flex items-center gap-4 mb-8">
<Link
href="/admin/projetos"
className="w-10 h-10 rounded-xl bg-white dark:bg-secondary border border-gray-200 dark:border-white/10 flex items-center justify-center text-gray-500 hover:text-primary hover:border-primary transition-colors shadow-sm"
>
<i className="ri-arrow-left-line text-xl"></i>
</Link>
<div>
<h1 className="text-3xl font-bold font-headline text-secondary dark:text-white mb-1">Novo Projeto</h1>
<p className="text-gray-500 dark:text-gray-400">Adicione um novo projeto ao portfólio.</p>
</div>
</div>
<form onSubmit={handleSubmit} className="space-y-8">
{/* Basic Info */}
<div className="bg-white dark:bg-secondary p-8 rounded-2xl border border-gray-200 dark:border-white/10 shadow-sm">
<h2 className="text-xl font-bold text-secondary dark:text-white mb-6 flex items-center gap-2">
<i className="ri-information-line text-primary"></i>
Informações Básicas
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="md:col-span-2">
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Título do Projeto</label>
<input
type="text"
value={formData.title}
onChange={(e) => setFormData({...formData, title: e.target.value})}
className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all"
placeholder="Ex: Adequação de Frota Coca-Cola"
required
/>
</div>
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Categoria</label>
<select
value={formData.category}
onChange={(e) => setFormData({...formData, category: e.target.value})}
className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all appearance-none cursor-pointer"
required
>
<option value="">Selecione uma categoria</option>
<option value="veicular">Engenharia Veicular</option>
<option value="mecanica">Projetos Mecânicos</option>
<option value="laudos">Laudos e Inspeções</option>
<option value="seguranca">Segurança do Trabalho</option>
</select>
</div>
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Cliente</label>
<input
type="text"
value={formData.client}
onChange={(e) => setFormData({...formData, client: e.target.value})}
className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all"
placeholder="Ex: Coca-Cola FEMSA"
/>
</div>
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Data de Conclusão</label>
<input
type="date"
value={formData.date}
onChange={(e) => setFormData({...formData, date: e.target.value})}
className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all"
/>
</div>
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Status</label>
<select
value={formData.status}
onChange={(e) => setFormData({...formData, status: e.target.value})}
className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all appearance-none cursor-pointer"
>
<option value="active">Concluído</option>
<option value="pending">Em Andamento</option>
<option value="draft">Rascunho</option>
</select>
</div>
<div className="md:col-span-2">
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Descrição Detalhada</label>
<textarea
value={formData.description}
onChange={(e) => setFormData({...formData, description: e.target.value})}
rows={6}
className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all resize-none"
placeholder="Descreva os detalhes técnicos, desafios e soluções do projeto..."
></textarea>
</div>
</div>
</div>
{/* Media */}
<div className="bg-white dark:bg-secondary p-8 rounded-2xl border border-gray-200 dark:border-white/10 shadow-sm">
<h2 className="text-xl font-bold text-secondary dark:text-white mb-6 flex items-center gap-2">
<i className="ri-image-line text-primary"></i>
Mídia
</h2>
<div className="space-y-6">
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Imagem de Capa</label>
<div className="border-2 border-dashed border-gray-300 dark:border-white/20 rounded-xl p-8 text-center hover:border-primary dark:hover:border-primary transition-colors cursor-pointer bg-gray-50 dark:bg-white/5">
<div className="w-16 h-16 bg-primary/10 rounded-full flex items-center justify-center text-primary mx-auto mb-4">
<i className="ri-upload-cloud-2-line text-3xl"></i>
</div>
<p className="text-gray-600 dark:text-gray-300 font-medium mb-1">Clique para fazer upload ou arraste e solte</p>
<p className="text-xs text-gray-400">PNG, JPG ou WEBP (Max. 2MB)</p>
</div>
</div>
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">Galeria de Fotos</label>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div className="aspect-square border-2 border-dashed border-gray-300 dark:border-white/20 rounded-xl flex flex-col items-center justify-center text-gray-400 hover:text-primary hover:border-primary transition-colors cursor-pointer bg-gray-50 dark:bg-white/5">
<i className="ri-add-line text-3xl mb-2"></i>
<span className="text-xs font-bold">Adicionar</span>
</div>
{/* Placeholders for uploaded images */}
{[1, 2].map((i) => (
<div key={i} className="aspect-square rounded-xl bg-gray-200 dark:bg-white/10 relative group overflow-hidden">
<div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
<button type="button" className="w-8 h-8 rounded-lg bg-white/20 hover:bg-white/40 text-white flex items-center justify-center backdrop-blur-sm transition-colors">
<i className="ri-delete-bin-line"></i>
</button>
</div>
</div>
))}
</div>
</div>
</div>
</div>
{/* Actions */}
<div className="flex items-center justify-end gap-4 pt-4">
<Link
href="/admin/projetos"
className="px-8 py-3 border border-gray-200 dark:border-white/10 text-gray-600 dark:text-gray-300 rounded-xl font-bold hover:bg-gray-50 dark:hover:bg-white/5 transition-colors"
>
Cancelar
</Link>
<button
type="submit"
disabled={loading}
className="px-8 py-3 bg-primary text-white rounded-xl font-bold hover:bg-orange-600 transition-colors shadow-lg shadow-primary/20 flex items-center gap-2 disabled:opacity-70 disabled:cursor-not-allowed"
>
{loading ? (
<>
<i className="ri-loader-4-line animate-spin"></i>
Salvando...
</>
) : (
<>
<i className="ri-save-line"></i>
Salvar Projeto
</>
)}
</button>
</div>
</form>
</div>
);
}