chore: integrate improve-integration

This commit is contained in:
Amruth Pillai
2026-07-08 19:08:31 +02:00
parent 73daf22b2f
commit 90105cb148
139 changed files with 6054 additions and 7793 deletions
@@ -0,0 +1,13 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const source = readFileSync("src/routes/builder/$resumeId/-sidebar/right/sections/layout/pages.tsx", "utf8");
describe("layout page header", () => {
it("uses container queries to prevent narrow sidebar control collisions", () => {
expect(source).toContain("@container bg-secondary/50");
expect(source).toContain("grid-cols-[minmax(0,1fr)_auto]");
expect(source).toContain("@max-[22rem]:grid-cols-1");
expect(source).toContain("flex min-w-0 flex-wrap");
});
});
@@ -297,31 +297,37 @@ function PageContainer({
return (
<div className="space-y-3 rounded-md border border-dashed bg-background/40">
<div className="flex items-center justify-between bg-secondary/50 px-4 py-3">
<div className="flex w-full items-center gap-4">
<span className="font-medium text-xs">
<Trans comment="Layout editor page label with 1-based page number">Page {pageIndex + 1}</Trans>
</span>
<label htmlFor={fullWidthSwitchId} className="flex cursor-pointer items-center gap-2">
<Switch
id={fullWidthSwitchId}
checked={page.fullWidth}
onCheckedChange={(checked) => onToggleFullWidth(pageIndex, checked)}
/>
<span className="font-medium text-muted-foreground text-xs">
<Trans comment="Layout editor toggle label that makes a page single-column">Full Width</Trans>
<div className="@container bg-secondary/50 px-4 py-3">
<div className="grid @max-[22rem]:grid-cols-1 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 gap-y-2">
<div className="flex min-w-0 flex-wrap items-center gap-x-4 gap-y-2">
<span className="font-medium text-xs">
<Trans comment="Layout editor page label with 1-based page number">Page {pageIndex + 1}</Trans>
</span>
</label>
</div>
{canDelete && (
<Button variant="ghost" onClick={() => onDelete(pageIndex)} className="h-5 w-auto gap-x-2.5 px-0!">
<TrashIcon />
<Trans>Delete Page</Trans>
</Button>
)}
<label htmlFor={fullWidthSwitchId} className="flex min-w-0 cursor-pointer items-center gap-2">
<Switch
id={fullWidthSwitchId}
checked={page.fullWidth}
onCheckedChange={(checked) => onToggleFullWidth(pageIndex, checked)}
/>
<span className="font-medium text-muted-foreground text-xs">
<Trans comment="Layout editor toggle label that makes a page single-column">Full Width</Trans>
</span>
</label>
</div>
{canDelete && (
<Button
variant="ghost"
onClick={() => onDelete(pageIndex)}
className="size-auto gap-x-2.5 justify-self-end p-0!"
>
<TrashIcon />
<Trans>Delete Page</Trans>
</Button>
)}
</div>
</div>
<div
@@ -1,5 +1,6 @@
// @vitest-environment happy-dom
import { readFileSync } from "node:fs";
import { fireEvent, render, screen } from "@testing-library/react";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import { i18n } from "@lingui/core";
@@ -64,4 +65,11 @@ describe("TemplateSectionBuilder", () => {
const img = screen.getByAltText("Ditto") as HTMLImageElement;
expect(img.src).toContain("/templates/jpg/ditto.jpg");
});
it("keeps the template preview inline instead of mounting a hover card", () => {
const source = readFileSync("src/routes/builder/$resumeId/-sidebar/right/sections/template.tsx", "utf8");
expect(source).not.toContain("@reactive-resume/ui/components/hover-card");
expect(source).not.toContain("HoverCardContent");
});
});
@@ -1,23 +1,12 @@
import { t } from "@lingui/core/macro";
import { useLingui } from "@lingui/react";
import { SwapIcon } from "@phosphor-icons/react";
import { lazy, Suspense } from "react";
import { Badge } from "@reactive-resume/ui/components/badge";
import { Button } from "@reactive-resume/ui/components/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@reactive-resume/ui/components/hover-card";
import { templates } from "@/dialogs/resume/template/data";
import { useDialogStore } from "@/dialogs/store";
import { useCurrentResume } from "@/features/resume/builder/draft";
import { SectionBase } from "../shared/section-base";
// Lazy so the browser PDF pipeline (pdf.js) loads only when a preview card actually opens, keeping it out
// of the SSR/module graph — mirrors the `ResumePreview` entry convention.
const TemplateLivePreview = lazy(() =>
import("@/features/resume/preview/template-live-preview").then((module) => ({
default: module.TemplateLivePreview,
})),
);
export function TemplateSectionBuilder() {
return (
<SectionBase type="template">
@@ -40,43 +29,19 @@ function TemplateSectionForm() {
return (
<div className="flex @md:flex-row flex-col items-stretch gap-x-4 gap-y-2">
<HoverCard>
<HoverCardTrigger
delay={300}
render={
<Button
variant="ghost"
onClick={onOpenTemplateGallery}
className="group/preview relative h-auto w-40 shrink-0 cursor-pointer p-0"
>
<div className="relative z-10 aspect-page size-full overflow-hidden rounded-md opacity-100 transition-opacity group-hover/preview:opacity-50">
<img src={metadata.imageUrl} alt={metadata.name} className="size-full object-cover" />
</div>
<Button
variant="ghost"
onClick={onOpenTemplateGallery}
className="group/preview relative h-auto w-40 shrink-0 cursor-pointer p-0"
>
<div className="relative z-10 aspect-page size-full overflow-hidden rounded-md opacity-100 transition-opacity group-hover/preview:opacity-50">
<img src={metadata.imageUrl} alt={metadata.name} className="size-full object-cover" />
</div>
<div className="absolute inset-0 flex items-center justify-center">
<SwapIcon size={48} weight="thin" className="size-12" />
</div>
</Button>
}
/>
<HoverCardContent side="right" align="start" className="w-64 p-1.5">
<Suspense
fallback={
<div className="aspect-page w-full overflow-hidden rounded-md bg-white">
<img src={metadata.imageUrl} alt={metadata.name} className="size-full object-contain" />
</div>
}
>
<TemplateLivePreview
data={resume.data}
template={template}
fallbackSrc={metadata.imageUrl}
alt={t`Live preview of your resume in the ${metadata.name} template`}
/>
</Suspense>
</HoverCardContent>
</HoverCard>
<div className="absolute inset-0 flex items-center justify-center">
<SwapIcon size={48} weight="thin" className="size-12" />
</div>
</Button>
<div className="flex flex-1 flex-col gap-y-4 @md:pt-1 @md:pb-3">
<div className="space-y-1">