mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 08:13:49 +10:00
77 lines
2.2 KiB
TypeScript
77 lines
2.2 KiB
TypeScript
import { t } from "@lingui/macro";
|
|
import type { ResumeDto } from "@reactive-resume/dto";
|
|
import { useCallback, useEffect } from "react";
|
|
import { Helmet } from "react-helmet-async";
|
|
import type { LoaderFunction } from "react-router";
|
|
import { redirect } from "react-router";
|
|
|
|
import { queryClient } from "@/client/libs/query-client";
|
|
import { findResumeById } from "@/client/services/resume";
|
|
import { useBuilderStore } from "@/client/stores/builder";
|
|
import { useResumeStore } from "@/client/stores/resume";
|
|
|
|
export const BuilderPage = () => {
|
|
const frameRef = useBuilderStore((state) => state.frame.ref);
|
|
const setFrameRef = useBuilderStore((state) => state.frame.setRef);
|
|
|
|
const resume = useResumeStore((state) => state.resume);
|
|
const title = useResumeStore((state) => state.resume.title);
|
|
|
|
const updateResumeInFrame = useCallback(() => {
|
|
const message = { type: "SET_RESUME", payload: resume.data };
|
|
|
|
setImmediate(() => {
|
|
frameRef?.contentWindow?.postMessage(message, "*");
|
|
});
|
|
}, [frameRef?.contentWindow, resume.data]);
|
|
|
|
// Send resume data to iframe on initial load
|
|
useEffect(() => {
|
|
if (!frameRef) return;
|
|
frameRef.addEventListener("load", updateResumeInFrame);
|
|
return () => {
|
|
frameRef.removeEventListener("load", updateResumeInFrame);
|
|
};
|
|
}, [frameRef]);
|
|
|
|
// Send resume data to iframe on change of resume data
|
|
useEffect(updateResumeInFrame, [resume.data]);
|
|
|
|
return (
|
|
<>
|
|
<Helmet>
|
|
<title>
|
|
{title} - {t`Reactive Resume`}
|
|
</title>
|
|
</Helmet>
|
|
|
|
<iframe
|
|
ref={setFrameRef}
|
|
title={resume.id}
|
|
src="/artboard/builder"
|
|
className="mt-16 w-screen"
|
|
style={{ height: `calc(100vh - 64px)` }}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export const builderLoader: LoaderFunction<ResumeDto> = async ({ params }) => {
|
|
try {
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
const id = params.id!;
|
|
|
|
const resume = await queryClient.fetchQuery({
|
|
queryKey: ["resume", { id }],
|
|
queryFn: () => findResumeById({ id }),
|
|
});
|
|
|
|
useResumeStore.setState({ resume });
|
|
useResumeStore.temporal.getState().clear();
|
|
|
|
return resume;
|
|
} catch {
|
|
return redirect("/dashboard");
|
|
}
|
|
};
|