Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Refactored metadata for contacts, administration, and Ulticards pages to utilize dynamic app names and descriptions. - Introduced new product pages for Ultiai, Ultical, Ulticards, Ultidrive, Ultimail, and Ultimeet with appropriate metadata. - Enhanced layout components to ensure consistent styling and functionality across new product sections. - Updated various components to replace hardcoded labels with dynamic references to improve maintainability and consistency.
132 lines
5.5 KiB
TypeScript
132 lines
5.5 KiB
TypeScript
"use client"
|
|
|
|
import { Icon } from "@iconify/react"
|
|
|
|
const ACCENT = "#4285F4"
|
|
|
|
type SourceCard = {
|
|
origin: string
|
|
originIcon: string
|
|
fields: { icon: string; value: string; kept: boolean }[]
|
|
}
|
|
|
|
const SOURCES: SourceCard[] = [
|
|
{
|
|
origin: "Importé de Google",
|
|
originIcon: "logos:google-icon",
|
|
fields: [
|
|
{ icon: "mdi:email-outline", value: "marc.dubois@example.com", kept: true },
|
|
{ icon: "mdi:phone-outline", value: "—", kept: false },
|
|
{ icon: "mdi:office-building-outline", value: "Studio Lumen", kept: true },
|
|
],
|
|
},
|
|
{
|
|
origin: "Découvert dans le mail",
|
|
originIcon: "mdi:email-search-outline",
|
|
fields: [
|
|
{ icon: "mdi:email-outline", value: "m.dubois@studio-lumen.fr", kept: true },
|
|
{ icon: "mdi:phone-outline", value: "+33 6 98 76 54 32", kept: true },
|
|
{ icon: "mdi:office-building-outline", value: "—", kept: false },
|
|
],
|
|
},
|
|
]
|
|
|
|
const MERGED = [
|
|
{ icon: "mdi:email-outline", value: "marc.dubois@example.com" },
|
|
{ icon: "mdi:email-outline", value: "m.dubois@studio-lumen.fr" },
|
|
{ icon: "mdi:phone-outline", value: "+33 6 98 76 54 32" },
|
|
{ icon: "mdi:office-building-outline", value: "Studio Lumen" },
|
|
]
|
|
|
|
/** Aperçu statique de la fusion de doublons — deux fiches sources combinées en une. */
|
|
export function UlticardsMergeDemo() {
|
|
return (
|
|
<div className="flex flex-col gap-3">
|
|
<div className="landing-glass-strong overflow-hidden rounded-2xl shadow-[0_32px_70px_-36px_rgba(30,40,90,0.45)]">
|
|
<div className="flex items-center gap-2.5 border-b border-[var(--landing-line)] px-4 py-3">
|
|
<Icon icon="mdi:call-merge" className="size-5" style={{ color: ACCENT }} aria-hidden />
|
|
<span className="text-sm font-semibold tracking-tight">Doublon détecté</span>
|
|
<span className="ml-auto rounded-full bg-[var(--landing-chip)] px-2 py-0.5 text-[11px] font-medium text-[var(--landing-muted)]">
|
|
Marc Dubois
|
|
</span>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-3 p-4 sm:grid-cols-2">
|
|
{SOURCES.map((card) => (
|
|
<div
|
|
key={card.origin}
|
|
className="rounded-xl border border-dashed border-[var(--landing-line)] bg-[var(--landing-chip)]/30 p-3"
|
|
>
|
|
<p className="mb-2 flex items-center gap-1.5 text-[11px] font-medium uppercase tracking-wide text-[var(--landing-muted)]">
|
|
<Icon icon={card.originIcon} className="size-3.5" aria-hidden />
|
|
{card.origin}
|
|
</p>
|
|
<ul className="flex flex-col gap-1.5">
|
|
{card.fields.map((field, index) => (
|
|
<li
|
|
key={index}
|
|
className="flex items-center gap-2 text-xs"
|
|
style={{ opacity: field.kept ? 1 : 0.4 }}
|
|
>
|
|
<Icon icon={field.icon} className="size-3.5 shrink-0 text-[var(--landing-muted)]" aria-hidden />
|
|
<span className="truncate text-[var(--landing-fg)]">{field.value}</span>
|
|
{field.kept ? (
|
|
<Icon
|
|
icon="mdi:check-circle"
|
|
className="ml-auto size-3.5 shrink-0"
|
|
style={{ color: ACCENT }}
|
|
aria-hidden
|
|
/>
|
|
) : null}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="flex items-center justify-center gap-2 pb-1 text-[var(--landing-muted)]">
|
|
<Icon icon="mdi:arrow-down" className="size-4" aria-hidden />
|
|
<span className="text-[11px] font-medium uppercase tracking-wide">Fiche fusionnée</span>
|
|
<Icon icon="mdi:arrow-down" className="size-4" aria-hidden />
|
|
</div>
|
|
|
|
<div className="border-t border-[var(--landing-line)] bg-[var(--landing-bg)]/60 p-4">
|
|
<div className="flex items-center gap-3">
|
|
<span
|
|
className="flex size-10 shrink-0 items-center justify-center rounded-full text-base font-semibold text-white"
|
|
style={{ backgroundColor: ACCENT }}
|
|
aria-hidden
|
|
>
|
|
M
|
|
</span>
|
|
<div className="min-w-0">
|
|
<p className="truncate text-sm font-semibold text-[var(--landing-fg)]">Marc Dubois</p>
|
|
<p className="truncate text-xs text-[var(--landing-muted)]">Studio Lumen</p>
|
|
</div>
|
|
<span
|
|
className="ml-auto flex h-8 shrink-0 items-center gap-1.5 rounded-full px-3 text-xs font-semibold text-white"
|
|
style={{ backgroundColor: ACCENT }}
|
|
>
|
|
<Icon icon="mdi:call-merge" className="size-4" aria-hidden />
|
|
Fusionner
|
|
</span>
|
|
</div>
|
|
<ul className="mt-3 grid grid-cols-1 gap-1.5 sm:grid-cols-2">
|
|
{MERGED.map((field, index) => (
|
|
<li key={index} className="flex items-center gap-2 text-xs">
|
|
<Icon icon={field.icon} className="size-3.5 shrink-0 text-[var(--landing-muted)]" aria-hidden />
|
|
<span className="truncate text-[var(--landing-fg)]">{field.value}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<p className="flex items-start gap-2 text-sm text-[var(--landing-muted)]">
|
|
<Icon icon="mdi:incognito" className="mt-0.5 size-4 shrink-0" aria-hidden />
|
|
Aperçu statique — import vCard, CSV ou Google, puis fusion en gardant le meilleur de chaque fiche.
|
|
</p>
|
|
</div>
|
|
)
|
|
}
|