Cases da SEV Moda Íntima e da Lavação 047; case no formato cliente, problema, entrega, mídia e contato, com detalhes técnicos recolhidos; sem GitHub, ressalvas e fontes de commit. /cases separa clientes e Laboratório. Serviços mostram o case de cliente certo e o bloco de investimento e prazo só aparece preenchido. Metadata social própria por página, not-found com noindex, sitemap com /ia.
92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import {
|
|
BrowserFrame,
|
|
displayUrl,
|
|
} from "@/app/components/showcase/BrowserFrame";
|
|
import { PhoneFrame } from "@/app/components/showcase/PhoneFrame";
|
|
import type { ShowcaseAssets } from "@/lib/project-showcase";
|
|
import { getCaseMedia } from "./case-media";
|
|
import "../../components/showcase/showcase.css";
|
|
|
|
function CaseVideo({
|
|
assets,
|
|
label,
|
|
className,
|
|
}: {
|
|
assets: ShowcaseAssets;
|
|
label: string;
|
|
className: string;
|
|
}) {
|
|
return (
|
|
<video
|
|
className={className}
|
|
controls
|
|
muted
|
|
loop
|
|
playsInline
|
|
preload="none"
|
|
poster={assets.poster}
|
|
width={assets.width}
|
|
height={assets.height}
|
|
aria-label={label}
|
|
disablePictureInPicture
|
|
>
|
|
{assets.sources.map((source) => (
|
|
<source key={source.src} src={source.src} type={source.type} />
|
|
))}
|
|
</video>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Pôster e vídeo do projeto: o site no computador (moldura de navegador) e no celular (moldura de celular).
|
|
* O vídeo só baixa quando a pessoa aperta o play. Sem captura gravada, não mostra nada.
|
|
*/
|
|
export function CaseMedia({
|
|
id,
|
|
title,
|
|
demoUrl,
|
|
}: {
|
|
id: string;
|
|
title: string;
|
|
demoUrl?: string | null;
|
|
}) {
|
|
const desktop = getCaseMedia(id, "desktop");
|
|
const mobile = getCaseMedia(id, "mobile");
|
|
if (!desktop && !mobile) return null;
|
|
|
|
return (
|
|
<div className="mt-sp-8 grid items-end gap-sp-8 md:grid-cols-[minmax(0,1fr)_auto]">
|
|
{desktop ? (
|
|
<figure className="min-w-0">
|
|
<BrowserFrame url={displayUrl({ demoUrl, title })}>
|
|
<div className="relative aspect-[16/10] bg-[#0a0a0a]">
|
|
<CaseVideo
|
|
assets={desktop}
|
|
label={`Vídeo do site ${title} no computador`}
|
|
className="absolute inset-0 h-full w-full object-cover object-top"
|
|
/>
|
|
</div>
|
|
</BrowserFrame>
|
|
<figcaption className="mt-sp-3 font-[family-name:var(--font-body)] text-[15px] text-white/70">
|
|
O site {title} no computador.
|
|
</figcaption>
|
|
</figure>
|
|
) : null}
|
|
{mobile ? (
|
|
<figure className="mx-auto w-[min(62vw,220px)] md:mx-0">
|
|
<PhoneFrame poster={mobile.poster}>
|
|
<CaseVideo
|
|
assets={mobile}
|
|
label={`Vídeo do site ${title} no celular`}
|
|
className="absolute inset-0 h-full w-full object-cover object-top"
|
|
/>
|
|
</PhoneFrame>
|
|
<figcaption className="mt-sp-3 text-center font-[family-name:var(--font-body)] text-[15px] text-white/70">
|
|
No celular.
|
|
</figcaption>
|
|
</figure>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|