Modulo makers3d desarrollado con codex V 0.0.1
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import { serverFetch } from "../../lib/api";
|
||||
|
||||
function toText(value: unknown, fallback = "") {
|
||||
return typeof value === "string" && value ? value : fallback;
|
||||
}
|
||||
|
||||
function toBool(value: unknown) {
|
||||
return value === true || value === "true";
|
||||
}
|
||||
|
||||
function asArray(value: unknown): string[] {
|
||||
return Array.isArray(value) ? value.map((item) => String(item)) : [];
|
||||
}
|
||||
|
||||
export default async function ServicePage({ params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params;
|
||||
const { service } = await serverFetch<{ service: Record<string, unknown> }>(`/services/${slug}`);
|
||||
|
||||
return (
|
||||
<main className="page-shell service-page">
|
||||
<div className="detail-grid">
|
||||
<section className="service-content">
|
||||
<section className="panel stack">
|
||||
<span className="eyebrow">Servicio publico</span>
|
||||
<h1 className="headline" style={{ fontSize: "clamp(2rem, 5vw, 3.1rem)" }}>{toText(service.title)}</h1>
|
||||
<p className="lead">{toText(service.description)}</p>
|
||||
<div className="badges">
|
||||
<span className="badge">{toText(service.category)}</span>
|
||||
<span className="badge">{toBool(service.local_pickup) ? "Retiro local" : "Solo envio"}</span>
|
||||
<span className="badge">{toBool(service.nationwide_shipping) ? "Envio nacional" : "Cobertura puntual"}</span>
|
||||
</div>
|
||||
<div className="meta-grid">
|
||||
<div className="stat-tile"><span className="stat-value">{String(service.lead_time_days || 4)} dias</span><span className="mini-note">Plazo orientativo</span></div>
|
||||
<div className="stat-tile"><span className="stat-value">Desde</span><span className="mini-note">${Math.round(Number(service.price_from_cents || 0) / 100).toLocaleString("es-AR")}</span></div>
|
||||
<div className="stat-tile"><span className="stat-value">Visible</span><span className="mini-note">En mapa y perfil</span></div>
|
||||
<div className="stat-tile"><span className="stat-value">Guiado</span><span className="mini-note">Contacto contextual</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="panel stack">
|
||||
<div className="section-head">
|
||||
<div className="stack" style={{ gap: 6 }}>
|
||||
<span className="eyebrow">Materiales y capacidades</span>
|
||||
<h2 className="section-title">Informacion pensada para decidir rapido</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div className="badges">
|
||||
{asArray(service.materials).map((item) => (
|
||||
<span key={item} className="badge">{item}</span>
|
||||
))}
|
||||
{asArray(service.technologies).map((item) => (
|
||||
<span key={item} className="badge">{item}</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="grid-cards">
|
||||
<article className="visual-card">
|
||||
<img className="thumb" src="/demo/work-dashboard-bracket.svg" alt="Uso" />
|
||||
<div className="visual-body">
|
||||
<strong>Uso principal</strong>
|
||||
<span className="mini-note">Piezas funcionales, prototipos y necesidades reales con restricciones claras.</span>
|
||||
</div>
|
||||
</article>
|
||||
<article className="visual-card">
|
||||
<img className="thumb" src="/demo/work-custom.svg" alt="Entrega" />
|
||||
<div className="visual-body">
|
||||
<strong>Entrega</strong>
|
||||
<span className="mini-note">Retiro local, envio o cobertura segun la configuracion del maker.</span>
|
||||
</div>
|
||||
</article>
|
||||
<article className="visual-card">
|
||||
<img className="thumb" src="/demo/work-coffee-hinge.svg" alt="Contexto" />
|
||||
<div className="visual-body">
|
||||
<strong>Consulta guiada</strong>
|
||||
<span className="mini-note">El cliente no llega en frio. Llega con referencia, urgencia y uso final.</span>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<aside className="stack">
|
||||
<section className="panel contact-card stack">
|
||||
<span className="eyebrow">Iniciar consulta</span>
|
||||
<h2 className="section-title">Pide este servicio con un flujo corto y util</h2>
|
||||
<Link
|
||||
href={`/consultas/nueva?makerId=${encodeURIComponent(String(service.maker_id))}&sourceType=service&sourceId=${encodeURIComponent(String(service.id))}&makerName=${encodeURIComponent(toText(service.maker_name, "Maker"))}&contextTitle=${encodeURIComponent(toText(service.title))}&returnTo=${encodeURIComponent(`/services/${slug}`)}`}
|
||||
className="button button-primary"
|
||||
>
|
||||
Abrir contacto guiado
|
||||
</Link>
|
||||
<Link href={`/makers/${toText(service.maker_slug)}`} className="button button-secondary">Ver maker</Link>
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user