ui cleanup
This commit is contained in:
@@ -15,15 +15,15 @@ export function AppShell() {
|
|||||||
const { user, logout } = useAuth();
|
const { user, logout } = useAuth();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen px-4 py-6 md:px-8">
|
<div className="min-h-screen px-4 py-5 xl:px-6 2xl:px-8">
|
||||||
<div className="mx-auto flex max-w-7xl gap-6">
|
<div className="mx-auto flex w-full max-w-[1760px] gap-4 2xl:gap-6">
|
||||||
<aside className="hidden w-72 shrink-0 flex-col rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel backdrop-blur md:flex">
|
<aside className="hidden w-72 shrink-0 flex-col rounded-[28px] border border-line/70 bg-surface/90 p-5 shadow-panel backdrop-blur md:flex 2xl:w-80">
|
||||||
<div>
|
<div>
|
||||||
<div className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">MRP Codex</div>
|
<div className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">MRP Codex</div>
|
||||||
<h1 className="mt-3 text-2xl font-extrabold text-text">Manufacturing foundation</h1>
|
<h1 className="mt-3 text-2xl font-extrabold text-text">Manufacturing foundation</h1>
|
||||||
<p className="mt-2 text-sm text-muted">Single-tenant platform shell with branding, auth, file storage, and planning foundations.</p>
|
<p className="mt-2 text-sm text-muted">Single-tenant platform shell with branding, auth, file storage, and planning foundations.</p>
|
||||||
</div>
|
</div>
|
||||||
<nav className="mt-8 space-y-2">
|
<nav className="mt-6 space-y-2">
|
||||||
{links.map((link) => (
|
{links.map((link) => (
|
||||||
<NavLink
|
<NavLink
|
||||||
key={link.to}
|
key={link.to}
|
||||||
@@ -51,14 +51,14 @@ export function AppShell() {
|
|||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
<main className="min-w-0 flex-1">
|
<main className="min-w-0 flex-1">
|
||||||
<div className="mb-6 flex items-center justify-between rounded-[28px] border border-line/70 bg-surface/90 px-6 py-5 shadow-panel backdrop-blur">
|
<div className="mb-4 flex items-center justify-between rounded-[28px] border border-line/70 bg-surface/90 px-5 py-4 shadow-panel backdrop-blur 2xl:px-6">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.22em] text-muted">Operations Command</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.22em] text-muted">Operations Command</p>
|
||||||
<h2 className="text-2xl font-bold text-text">Foundation Console</h2>
|
<h2 className="text-2xl font-bold text-text">Foundation Console</h2>
|
||||||
</div>
|
</div>
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
</div>
|
</div>
|
||||||
<nav className="mb-6 flex gap-3 overflow-x-auto rounded-[24px] border border-line/70 bg-surface/85 p-3 shadow-panel backdrop-blur md:hidden">
|
<nav className="mb-4 flex gap-3 overflow-x-auto rounded-[24px] border border-line/70 bg-surface/85 p-3 shadow-panel backdrop-blur md:hidden">
|
||||||
{links.map((link) => (
|
{links.map((link) => (
|
||||||
<NavLink
|
<NavLink
|
||||||
key={link.to}
|
key={link.to}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ interface CrmContactEntryFormProps {
|
|||||||
|
|
||||||
export function CrmContactEntryForm({ form, isSaving, status, onChange, onSubmit }: CrmContactEntryFormProps) {
|
export function CrmContactEntryForm({ form, isSaving, status, onChange, onSubmit }: CrmContactEntryFormProps) {
|
||||||
return (
|
return (
|
||||||
<form className="space-y-5" onSubmit={onSubmit}>
|
<form className="space-y-4" onSubmit={onSubmit}>
|
||||||
<div className="grid gap-5 md:grid-cols-[0.9fr_1.1fr]">
|
<div className="grid gap-4 xl:grid-cols-[minmax(0,0.9fr)_minmax(220px,1.1fr)]">
|
||||||
<label className="block">
|
<label className="block">
|
||||||
<span className="mb-2 block text-sm font-semibold text-text">Interaction type</span>
|
<span className="mb-2 block text-sm font-semibold text-text">Interaction type</span>
|
||||||
<select
|
<select
|
||||||
@@ -57,8 +57,8 @@ export function CrmContactEntryForm({ form, isSaving, status, onChange, onSubmit
|
|||||||
placeholder="Capture what happened, follow-ups, and commitments."
|
placeholder="Capture what happened, follow-ups, and commitments."
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div className="flex items-center justify-between rounded-2xl border border-line/70 bg-page/70 px-4 py-4">
|
<div className="flex flex-col gap-3 rounded-2xl border border-line/70 bg-page/70 px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
|
||||||
<span className="text-sm text-muted">{status}</span>
|
<span className="min-w-0 text-sm text-muted">{status}</span>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isSaving}
|
disabled={isSaving}
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ export function CrmDetailPage({ entity }: CrmDetailPageProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="space-y-6">
|
<section className="space-y-4">
|
||||||
<div className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel">
|
<div className="rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel 2xl:p-7">
|
||||||
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">CRM Detail</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">CRM Detail</p>
|
||||||
@@ -124,10 +124,10 @@ export function CrmDetailPage({ entity }: CrmDetailPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-6 xl:grid-cols-[1.15fr_0.85fr]">
|
<div className="grid gap-4 2xl:grid-cols-[minmax(0,1.2fr)_minmax(320px,0.8fr)]">
|
||||||
<article className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel">
|
<article className="min-w-0 rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel 2xl:p-7">
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Contact</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Contact</p>
|
||||||
<dl className="mt-6 grid gap-5 md:grid-cols-2">
|
<dl className="mt-5 grid gap-4 xl:grid-cols-2">
|
||||||
<div>
|
<div>
|
||||||
<dt className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Email</dt>
|
<dt className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Email</dt>
|
||||||
<dd className="mt-2 text-base text-text">{record.email}</dd>
|
<dd className="mt-2 text-base text-text">{record.email}</dd>
|
||||||
@@ -146,7 +146,7 @@ export function CrmDetailPage({ entity }: CrmDetailPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</article>
|
</article>
|
||||||
<article className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel">
|
<article className="min-w-0 rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel 2xl:p-7">
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Internal Notes</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Internal Notes</p>
|
||||||
<p className="mt-4 whitespace-pre-line text-sm leading-7 text-text">
|
<p className="mt-4 whitespace-pre-line text-sm leading-7 text-text">
|
||||||
{record.notes || "No internal notes recorded for this account yet."}
|
{record.notes || "No internal notes recorded for this account yet."}
|
||||||
@@ -156,9 +156,9 @@ export function CrmDetailPage({ entity }: CrmDetailPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
<section className="grid gap-6 xl:grid-cols-[0.85fr_1.15fr]">
|
<section className="grid gap-4 2xl:grid-cols-[minmax(360px,0.88fr)_minmax(0,1.12fr)]">
|
||||||
{canManage ? (
|
{canManage ? (
|
||||||
<article className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel">
|
<article className="min-w-0 rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel 2xl:p-7">
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Contact History</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Contact History</p>
|
||||||
<h4 className="mt-3 text-xl font-bold text-text">Add timeline entry</h4>
|
<h4 className="mt-3 text-xl font-bold text-text">Add timeline entry</h4>
|
||||||
<p className="mt-2 text-sm text-muted">
|
<p className="mt-2 text-sm text-muted">
|
||||||
@@ -175,7 +175,7 @@ export function CrmDetailPage({ entity }: CrmDetailPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
) : null}
|
) : null}
|
||||||
<article className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel">
|
<article className="min-w-0 rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel 2xl:p-7">
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Timeline</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Timeline</p>
|
||||||
<h4 className="mt-3 text-xl font-bold text-text">Recent interactions</h4>
|
<h4 className="mt-3 text-xl font-bold text-text">Recent interactions</h4>
|
||||||
{record.contactHistory.length === 0 ? (
|
{record.contactHistory.length === 0 ? (
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export function CrmFormPage({ entity, mode }: CrmFormPageProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="space-y-6" onSubmit={handleSubmit}>
|
<form className="space-y-6" onSubmit={handleSubmit}>
|
||||||
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel">
|
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel 2xl:p-7">
|
||||||
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">CRM Editor</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">CRM Editor</p>
|
||||||
@@ -106,10 +106,10 @@ export function CrmFormPage({ entity, mode }: CrmFormPageProps) {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section className="space-y-6 rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel">
|
<section className="space-y-5 rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel 2xl:p-7">
|
||||||
<CrmRecordForm form={form} onChange={updateField} />
|
<CrmRecordForm form={form} onChange={updateField} />
|
||||||
<div className="flex items-center justify-between rounded-2xl border border-line/70 bg-page/70 px-4 py-4">
|
<div className="flex flex-col gap-3 rounded-2xl border border-line/70 bg-page/70 px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
|
||||||
<span className="text-sm text-muted">{status}</span>
|
<span className="min-w-0 text-sm text-muted">{status}</span>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isSaving}
|
disabled={isSaving}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export function CrmRecordForm({ form, onChange }: CrmRecordFormProps) {
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<div className="grid gap-5 md:grid-cols-2">
|
<div className="grid gap-4 xl:grid-cols-2 2xl:grid-cols-3">
|
||||||
{fields.map((field) => (
|
{fields.map((field) => (
|
||||||
<label key={String(field.key)} className="block">
|
<label key={String(field.key)} className="block">
|
||||||
<span className="mb-2 block text-sm font-semibold text-text">{field.label}</span>
|
<span className="mb-2 block text-sm font-semibold text-text">{field.label}</span>
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ export function CompanySettingsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="space-y-6" onSubmit={handleSave}>
|
<form className="space-y-6" onSubmit={handleSave}>
|
||||||
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel backdrop-blur">
|
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel backdrop-blur 2xl:p-7">
|
||||||
<div className="flex flex-col gap-6 lg:flex-row lg:items-start lg:justify-between">
|
<div className="flex flex-col gap-6 lg:flex-row lg:items-start lg:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Company Profile</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Company Profile</p>
|
||||||
@@ -160,7 +160,7 @@ export function CompanySettingsPage() {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 grid gap-5 md:grid-cols-2">
|
<div className="mt-6 grid gap-4 xl:grid-cols-2 2xl:grid-cols-3">
|
||||||
{[
|
{[
|
||||||
["companyName", "Company name"],
|
["companyName", "Company name"],
|
||||||
["legalName", "Legal name"],
|
["legalName", "Legal name"],
|
||||||
@@ -186,9 +186,9 @@ export function CompanySettingsPage() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-8 shadow-panel backdrop-blur">
|
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-6 shadow-panel backdrop-blur 2xl:p-7">
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Theme</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Theme</p>
|
||||||
<div className="mt-6 grid gap-5 md:grid-cols-2 xl:grid-cols-4">
|
<div className="mt-5 grid gap-4 md:grid-cols-2 2xl:grid-cols-4">
|
||||||
<label className="block">
|
<label className="block">
|
||||||
<span className="mb-2 block text-sm font-semibold text-text">Primary color</span>
|
<span className="mb-2 block text-sm font-semibold text-text">Primary color</span>
|
||||||
<input type="color" value={form.theme.primaryColor} onChange={(event) => updateField("theme", { ...form.theme, primaryColor: event.target.value })} className="h-12 w-full rounded-2xl border border-line/70 bg-page p-2" />
|
<input type="color" value={form.theme.primaryColor} onChange={(event) => updateField("theme", { ...form.theme, primaryColor: event.target.value })} className="h-12 w-full rounded-2xl border border-line/70 bg-page p-2" />
|
||||||
@@ -206,9 +206,9 @@ export function CompanySettingsPage() {
|
|||||||
<input value={form.theme.fontFamily} onChange={(event) => updateField("theme", { ...form.theme, fontFamily: event.target.value })} className="w-full rounded-2xl border border-line/70 bg-page px-4 py-3 text-text outline-none transition focus:border-brand" />
|
<input value={form.theme.fontFamily} onChange={(event) => updateField("theme", { ...form.theme, fontFamily: event.target.value })} className="w-full rounded-2xl border border-line/70 bg-page px-4 py-3 text-text outline-none transition focus:border-brand" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-6 flex items-center justify-between rounded-2xl border border-line/70 bg-page/70 px-4 py-4">
|
<div className="mt-5 flex flex-col gap-3 rounded-2xl border border-line/70 bg-page/70 px-4 py-4 lg:flex-row lg:items-center lg:justify-between">
|
||||||
<span className="text-sm text-muted">{status}</span>
|
<span className="min-w-0 text-sm text-muted">{status}</span>
|
||||||
<div className="flex gap-3">
|
<div className="flex flex-wrap gap-3">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handlePdfPreview}
|
onClick={handlePdfPreview}
|
||||||
|
|||||||
Reference in New Issue
Block a user