185 lines
7.1 KiB
TypeScript
185 lines
7.1 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
import { Building2, Mail, Phone, Globe, FileText, Hash, Users, DollarSign, CalendarDays } from "lucide-react"
|
|
|
|
interface Profile {
|
|
id: string
|
|
customer_type: string
|
|
source: string
|
|
customer_notes: string
|
|
status_name: string
|
|
status_color: string
|
|
company_name: string
|
|
registration_number: string
|
|
tax_id: string
|
|
website: string
|
|
industry: string
|
|
company_size: string
|
|
annual_revenue: string
|
|
first_name: string
|
|
last_name: string
|
|
job_title: string
|
|
}
|
|
|
|
interface Contact {
|
|
type: string
|
|
value: string
|
|
label: string
|
|
is_primary: boolean
|
|
}
|
|
|
|
export default function ClientProfile() {
|
|
const [profile, setProfile] = useState<Profile | null>(null)
|
|
const [contacts, setContacts] = useState<Contact[]>([])
|
|
|
|
useEffect(() => {
|
|
fetch("/client-portal/api/profile", { credentials: "include" })
|
|
.then((r) => r.json())
|
|
.then((d) => {
|
|
setProfile(d.profile || null)
|
|
setContacts(d.contacts || [])
|
|
})
|
|
.catch(() => {})
|
|
}, [])
|
|
|
|
if (!profile) {
|
|
return (
|
|
<div className="flex items-center justify-center h-32">
|
|
<div className="w-6 h-6 border-2 border-[#1BB0CE] border-t-transparent rounded-full animate-spin" />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const isCompany = profile.customer_type === "company"
|
|
const name = isCompany ? profile.company_name : `${profile.first_name || ""} ${profile.last_name || ""}`.trim()
|
|
|
|
return (
|
|
<div>
|
|
<h1 className="text-xl font-bold text-white mb-1">Profile</h1>
|
|
<p className="text-sm text-[#6a6a75] mb-6">Your account and company information</p>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
{/* Main info card */}
|
|
<div className="lg:col-span-2 space-y-4">
|
|
<div className="bg-[#0d1117] border border-[#1a1a24] rounded-xl p-6">
|
|
<div className="flex items-center gap-4 mb-5">
|
|
<div className="w-14 h-14 rounded-xl bg-[#1BB0CE]/10 flex items-center justify-center">
|
|
<Building2 className="h-7 w-7 text-[#1BB0CE]" />
|
|
</div>
|
|
<div>
|
|
<h2 className="text-lg font-semibold text-white">{name || "Unnamed"}</h2>
|
|
<div className="flex items-center gap-2 mt-1">
|
|
<span className="text-[11px] px-2 py-0.5 rounded-full" style={{ backgroundColor: `${profile.status_color}15`, color: profile.status_color }}>
|
|
{profile.status_name}
|
|
</span>
|
|
<span className="text-[11px] text-[#6a6a75]">{isCompany ? "Company" : "Individual"}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
{isCompany && profile.industry && (
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<Hash className="h-4 w-4 text-[#6a6a75]" />
|
|
<div>
|
|
<p className="text-[#6a6a75] text-[11px]">Industry</p>
|
|
<p className="text-white">{profile.industry}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{isCompany && profile.registration_number && (
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<FileText className="h-4 w-4 text-[#6a6a75]" />
|
|
<div>
|
|
<p className="text-[#6a6a75] text-[11px]">Registration</p>
|
|
<p className="text-white">{profile.registration_number}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{profile.tax_id && (
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<FileText className="h-4 w-4 text-[#6a6a75]" />
|
|
<div>
|
|
<p className="text-[#6a6a75] text-[11px]">Tax / VAT</p>
|
|
<p className="text-white">{profile.tax_id}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{isCompany && profile.company_size && (
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<Users className="h-4 w-4 text-[#6a6a75]" />
|
|
<div>
|
|
<p className="text-[#6a6a75] text-[11px]">Company Size</p>
|
|
<p className="text-white">{profile.company_size}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{isCompany && profile.annual_revenue && (
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<DollarSign className="h-4 w-4 text-[#6a6a75]" />
|
|
<div>
|
|
<p className="text-[#6a6a75] text-[11px]">Annual Revenue</p>
|
|
<p className="text-white">{Number(profile.annual_revenue).toLocaleString()}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{profile.website && (
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<Globe className="h-4 w-4 text-[#6a6a75]" />
|
|
<div>
|
|
<p className="text-[#6a6a75] text-[11px]">Website</p>
|
|
<p className="text-[#1BB0CE]">{profile.website}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{!isCompany && profile.job_title && (
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<Hash className="h-4 w-4 text-[#6a6a75]" />
|
|
<div>
|
|
<p className="text-[#6a6a75] text-[11px]">Job Title</p>
|
|
<p className="text-white">{profile.job_title}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{profile.customer_notes && (
|
|
<div className="bg-[#0d1117] border border-[#1a1a24] rounded-xl p-5">
|
|
<h3 className="text-sm font-medium text-white mb-2">Notes</h3>
|
|
<p className="text-sm text-[#8a8a95]">{profile.customer_notes}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Contacts sidebar */}
|
|
<div className="space-y-3">
|
|
{(contacts || []).map((c, i) => (
|
|
<div key={i} className="bg-[#0d1117] border border-[#1a1a24] rounded-xl p-4">
|
|
<div className="flex items-center gap-3">
|
|
{c.type === "email" ? <Mail className="h-4 w-4 text-[#1BB0CE]" /> :
|
|
c.type === "phone" || c.type === "mobile" ? <Phone className="h-4 w-4 text-[#1BB0CE]" /> :
|
|
c.type === "website" ? <Globe className="h-4 w-4 text-[#1BB0CE]" /> :
|
|
<Hash className="h-4 w-4 text-[#1BB0CE]" />}
|
|
<div>
|
|
<p className="text-[11px] text-[#6a6a75]">{c.label || c.type}</p>
|
|
<p className="text-sm text-white">{c.value}</p>
|
|
</div>
|
|
</div>
|
|
{c.is_primary && (
|
|
<span className="text-[10px] text-[#1BB0CE] mt-1.5 block">Primary</span>
|
|
)}
|
|
</div>
|
|
))}
|
|
{contacts.length === 0 && (
|
|
<div className="text-center py-8 text-sm text-[#6a6a75] bg-[#0d1117] border border-[#1a1a24] rounded-xl">
|
|
No contact info
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|