mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-23 23:02:17 +10:00
chore: integrate improve-integration
This commit is contained in:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user