| "use client"; |
|
|
| import { useState } from "react"; |
| import type { CompanyProfile as CompanyProfileType } from "../lib/types"; |
|
|
| type Props = { |
| profile: CompanyProfileType; |
| onSave: (profile: CompanyProfileType) => void; |
| }; |
|
|
| export default function CompanyProfile({ profile, onSave }: Props) { |
| const [form, setForm] = useState(profile); |
| |
| |
| const [servicesStr, setServicesStr] = useState(profile.services.join(", ")); |
| const [certsStr, setCertsStr] = useState(profile.certifications?.join(", ") || ""); |
| const [regionsStr, setRegionsStr] = useState(profile.regions?.join(", ") || ""); |
| const [docsStr, setDocsStr] = useState(profile.documents_available?.join(", ") || ""); |
| const [keywordsStr, setKeywordsStr] = useState(profile.keywords?.join(", ") || ""); |
|
|
| const [saving, setSaving] = useState(false); |
| const [saveStatus, setSaveStatus] = useState<"idle" | "saving" | "success" | "error">("idle"); |
|
|
| const handleSave = async () => { |
| console.log("[CompanyProfile] Clicked Save Profile"); |
| setSaving(true); |
| setSaveStatus("saving"); |
| try { |
| const updatedProfile = { |
| ...form, |
| services: servicesStr.split(",").map((s) => s.trim()).filter(Boolean), |
| certifications: certsStr.split(",").map((s) => s.trim()).filter(Boolean), |
| regions: regionsStr.split(",").map((s) => s.trim()).filter(Boolean), |
| documents_available: docsStr.split(",").map((s) => s.trim()).filter(Boolean), |
| keywords: keywordsStr.split(",").map((s) => s.trim()).filter(Boolean), |
| }; |
| |
| console.log("[CompanyProfile] Sending to onSave:", updatedProfile); |
| await onSave(updatedProfile); |
| |
| setSaveStatus("success"); |
| setTimeout(() => setSaveStatus("idle"), 3000); |
| } catch (e) { |
| console.error("[CompanyProfile] Save failed", e); |
| setSaveStatus("error"); |
| setTimeout(() => setSaveStatus("idle"), 3000); |
| } finally { |
| setSaving(false); |
| } |
| }; |
|
|
| return ( |
| <div className="space-y-6"> |
| <div className="grid gap-6 lg:grid-cols-2"> |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Company name</span> |
| <input |
| value={form.name} |
| onChange={(event) => setForm({ ...form, name: event.target.value })} |
| className="mt-3 w-full rounded-2xl border border-slate-800 bg-slate-900 px-4 py-3 text-white outline-none" |
| /> |
| </label> |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Industry</span> |
| <input |
| value={form.industry} |
| onChange={(event) => setForm({ ...form, industry: event.target.value })} |
| className="mt-3 w-full rounded-2xl border border-slate-800 bg-slate-900 px-4 py-3 text-white outline-none" |
| /> |
| </label> |
| </div> |
| |
| <div className="grid gap-6 lg:grid-cols-2"> |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Services</span> |
| <input |
| value={servicesStr} |
| onChange={(event) => setServicesStr(event.target.value)} |
| placeholder="AI automation, web apps, data dashboards" |
| className="mt-3 w-full rounded-2xl border border-slate-800 bg-slate-900 px-4 py-3 text-white outline-none" |
| /> |
| </label> |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Experience</span> |
| <input |
| value={form.experience} |
| onChange={(event) => setForm({ ...form, experience: event.target.value })} |
| className="mt-3 w-full rounded-2xl border border-slate-800 bg-slate-900 px-4 py-3 text-white outline-none" |
| /> |
| </label> |
| </div> |
| |
| <div className="grid gap-6 lg:grid-cols-2"> |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Certifications</span> |
| <input |
| value={certsStr} |
| onChange={(event) => setCertsStr(event.target.value)} |
| placeholder="ISO 9001, ISO 27001" |
| className="mt-3 w-full rounded-2xl border border-slate-800 bg-slate-900 px-4 py-3 text-white outline-none" |
| /> |
| </label> |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Regions</span> |
| <input |
| value={regionsStr} |
| onChange={(event) => setRegionsStr(event.target.value)} |
| placeholder="Metropolitana, Valparaíso" |
| className="mt-3 w-full rounded-2xl border border-slate-800 bg-slate-900 px-4 py-3 text-white outline-none" |
| /> |
| </label> |
| </div> |
| |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Documents available</span> |
| <input |
| value={docsStr} |
| onChange={(event) => setDocsStr(event.target.value)} |
| placeholder="RUT, Portfolio, Financial statements" |
| className="mt-3 w-full rounded-2xl border border-slate-800 bg-slate-900 px-4 py-3 text-white outline-none" |
| /> |
| </label> |
| |
| <label className="block rounded-3xl border border-slate-800 bg-slate-950/80 p-5"> |
| <span className="text-sm text-slate-400">Keywords (for recommendations)</span> |
| <input |
| value={keywordsStr} |
| onChange={(event) => setKeywordsStr(event.target.value)} |
| placeholder="software, AI, development, consulting" |
| className="mt-3 w-full rounded-2xl border border-indigo-500/30 bg-slate-900 px-4 py-3 text-white outline-none focus:border-indigo-500 transition-all shadow-[0_0_15px_rgba(99,102,241,0.05)]" |
| /> |
| <p className="text-[10px] text-slate-500 mt-2 font-mono uppercase tracking-widest">Separate with commas. These determine your Dashboard recommendations.</p> |
| </label> |
| |
| <div className="flex justify-center pt-8 pb-4"> |
| <button |
| type="button" |
| onClick={handleSave} |
| disabled={saving} |
| className={`group relative overflow-hidden rounded-2xl px-16 py-5 font-bold text-slate-950 transition-all active:scale-95 shadow-2xl ${ |
| saveStatus === "success" ? "bg-green-500 shadow-green-500/40" : |
| saveStatus === "error" ? "bg-red-500 shadow-red-500/40" : |
| "bg-cyan hover:bg-sky shadow-cyan/40" |
| } ${saving ? "opacity-70 cursor-wait" : "cursor-pointer"}`} |
| > |
| <span className="relative z-10 flex items-center gap-3"> |
| {saveStatus === "idle" && "Save Profile"} |
| {saveStatus === "saving" && ( |
| <> |
| <span className="animate-spin text-xl">⏳</span> |
| Saving... |
| </> |
| )} |
| {saveStatus === "success" && ( |
| <> |
| <span className="text-xl">✅</span> |
| Saved! |
| </> |
| )} |
| {saveStatus === "error" && ( |
| <> |
| <span className="text-xl">❌</span> |
| Error! |
| </> |
| )} |
| </span> |
| {saveStatus === "idle" && ( |
| <div className="absolute inset-0 bg-gradient-to-r from-white/30 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" /> |
| )} |
| </button> |
| </div> |
| </div> |
| ); |
| } |
|
|