()(
immer((set) => ({
- transform: {
+ frame: {
ref: null,
setRef: (ref) => {
set((state) => {
- state.transform.ref = ref;
+ // @ts-expect-error Unable to set ref type
+ state.frame.ref = ref;
});
},
},
diff --git a/apps/client/vite.config.ts b/apps/client/vite.config.ts
index 6cd0e9738..2825dff4f 100644
--- a/apps/client/vite.config.ts
+++ b/apps/client/vite.config.ts
@@ -21,11 +21,6 @@ export default defineConfig({
fs: { allow: [searchForWorkspaceRoot(process.cwd())] },
},
- preview: {
- host: true,
- port: +(process.env.__DEV__CLIENT_PORT ?? 5173),
- },
-
plugins: [react(), nxViteTsPaths(), splitVendorChunkPlugin()],
test: {
diff --git a/apps/server/src/app.module.ts b/apps/server/src/app.module.ts
index c62e81936..44904d9ae 100644
--- a/apps/server/src/app.module.ts
+++ b/apps/server/src/app.module.ts
@@ -27,10 +27,6 @@ import { UtilsModule } from "./utils/utils.module";
CacheModule,
UtilsModule,
HealthModule,
- ServeStaticModule.forRoot({
- rootPath: join(__dirname, "..", "client"),
- exclude: ["/api*", "/docs*"],
- }),
// Feature Modules
AuthModule.register(),
@@ -38,6 +34,16 @@ import { UtilsModule } from "./utils/utils.module";
ResumeModule,
StorageModule,
PrinterModule,
+
+ // Static Assets
+ ServeStaticModule.forRoot({
+ serveRoot: "/artboard",
+ rootPath: join(__dirname, "..", "artboard"),
+ }),
+ ServeStaticModule.forRoot({
+ renderPath: "/*",
+ rootPath: join(__dirname, "..", "client"),
+ }),
],
providers: [
{
diff --git a/apps/server/src/printer/printer.service.ts b/apps/server/src/printer/printer.service.ts
index 724484c14..6ad36c184 100644
--- a/apps/server/src/printer/printer.service.ts
+++ b/apps/server/src/printer/printer.service.ts
@@ -4,7 +4,7 @@ import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import fontkit from "@pdf-lib/fontkit";
import { ResumeDto } from "@reactive-resume/dto";
-import { getFontUrls, pageSizeMap, withTimeout } from "@reactive-resume/utils";
+import { getFontUrls, withTimeout } from "@reactive-resume/utils";
import retry from "async-retry";
import { readFile } from "fs/promises";
import { join } from "path";
@@ -16,7 +16,6 @@ import { ErrorMessage } from "../constants/error-message";
import { StorageService } from "../storage/storage.service";
import { UtilsService } from "../utils/utils.service";
-const MM_TO_PX = 3.78;
const PRINTER_TIMEOUT = 10000; // 10 seconds
@Injectable()
@@ -114,59 +113,38 @@ export class PrinterService {
}
// Set the data of the resume to be printed in the browser's session storage
- const format = resume.data.metadata.page.format;
const numPages = resume.data.metadata.layout.length;
- await page.evaluateOnNewDocument((data: string) => {
- sessionStorage.setItem("resume", data);
- }, JSON.stringify(resume.data));
+ await page.evaluateOnNewDocument((data) => {
+ sessionStorage.setItem("resume", JSON.stringify(data));
+ }, resume.data);
- await page.goto(`${url}/printer`, { waitUntil: "networkidle0" });
- await page.emulateMediaType("print");
+ await page.goto(`${url}/artboard/preview`, { waitUntil: "networkidle0" });
const pagesBuffer: Buffer[] = [];
- // Hide all the pages (elements with [data-page] attribute) using CSS
- const hidePages = () => {
- return page.$eval("iframe", (frame) => {
- frame.contentDocument?.documentElement.querySelectorAll("[data-page]").forEach((page) => {
- page.setAttribute("style", "display: none");
- });
- });
- };
+ const processPage = async (index: number) => {
+ const pageElement = await page.$(`[data-page="${index}"]`);
+ const width = (await (await pageElement?.getProperty("scrollWidth"))?.jsonValue()) ?? 0;
+ const height = (await (await pageElement?.getProperty("scrollHeight"))?.jsonValue()) ?? 0;
- const processPage = (index: number) => {
- // Calculate the height of the page based on the format, convert mm to pixels
- const pageSize = {
- width: pageSizeMap[format].width * MM_TO_PX,
- height: pageSizeMap[format].height * MM_TO_PX,
- };
-
- return page.$eval(
- "iframe",
- (frame, index, pageSize) => {
- const page = frame.contentDocument?.querySelector(`[data-page="${index}"]`);
- page?.setAttribute("style", "display: block");
-
- return {
- width: Math.max(pageSize.width, page?.scrollWidth ?? 0),
- height: Math.max(pageSize.height, page?.scrollHeight ?? 0),
- };
- },
- index,
- pageSize,
- );
+ const tempHtml = await page.evaluate((element: HTMLDivElement) => {
+ const clonedElement = element.cloneNode(true) as HTMLDivElement;
+ const tempHtml = document.body.innerHTML;
+ document.body.innerHTML = `${clonedElement.outerHTML}`;
+ return tempHtml;
+ }, pageElement);
+
+ pagesBuffer.push(await page.pdf({ width, height }));
+
+ await page.evaluate((tempHtml: string) => {
+ document.body.innerHTML = tempHtml;
+ }, tempHtml);
};
// Loop through all the pages and print them, by first displaying them, printing the PDF and then hiding them back
for (let index = 1; index <= numPages; index++) {
- await hidePages();
-
- const { width, height } = await processPage(index);
- const buffer = await page.pdf({ width, height });
- pagesBuffer.push(buffer);
-
- await hidePages();
+ await processPage(index);
}
// Using 'pdf-lib', merge all the pages from their buffers into a single PDF
@@ -265,18 +243,13 @@ export class PrinterService {
}
// Set the data of the resume to be printed in the browser's session storage
- const format = resume.data.metadata.page.format;
-
await page.evaluateOnNewDocument((data: string) => {
sessionStorage.setItem("resume", data);
}, JSON.stringify(resume.data));
- await page.setViewport({
- width: Math.round(pageSizeMap[format].width * MM_TO_PX),
- height: Math.round(pageSizeMap[format].height * MM_TO_PX),
- });
+ await page.setViewport({ width: 794, height: 1123 });
- await page.goto(`${url}/printer`, { waitUntil: "networkidle0" });
+ await page.goto(`${url}/artboard/preview`, { waitUntil: "networkidle0" });
// Save the JPEG to storage and return the URL
// Store the URL in cache for future requests, under the previously generated hash digest
diff --git a/apps/server/src/resume/resume.controller.ts b/apps/server/src/resume/resume.controller.ts
index 9b1871e65..dde367ecb 100644
--- a/apps/server/src/resume/resume.controller.ts
+++ b/apps/server/src/resume/resume.controller.ts
@@ -110,8 +110,8 @@ export class ResumeController {
@Delete(":id")
@UseGuards(TwoFactorGuard)
- async remove(@User() user: UserEntity, @Param("id") id: string) {
- await this.resumeService.remove(user.id, id);
+ remove(@User() user: UserEntity, @Param("id") id: string) {
+ return this.resumeService.remove(user.id, id);
}
@Get("/print/:id")
@@ -122,6 +122,7 @@ export class ResumeController {
return { url };
} catch (error) {
+ console.log(error);
Logger.error(error);
throw new InternalServerErrorException(error);
}
diff --git a/apps/server/src/resume/resume.service.ts b/apps/server/src/resume/resume.service.ts
index 30135f4c2..999ac56a2 100644
--- a/apps/server/src/resume/resume.service.ts
+++ b/apps/server/src/resume/resume.service.ts
@@ -179,10 +179,9 @@ export class ResumeService {
// Remove files in storage, and their cached keys
this.storageService.deleteObject(userId, "resumes", id),
this.storageService.deleteObject(userId, "previews", id),
-
- // Remove resume from database
- this.prisma.resume.delete({ where: { userId_id: { userId, id } } }),
]);
+
+ return this.prisma.resume.delete({ where: { userId_id: { userId, id } } });
}
async printResume(resume: ResumeDto) {
diff --git a/libs/hooks/src/hooks/use-template.ts b/libs/hooks/src/hooks/use-template.ts
deleted file mode 100644
index 3bfe95c37..000000000
--- a/libs/hooks/src/hooks/use-template.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { templatesList } from "@reactive-resume/templates";
-import { useMemo } from "react";
-
-export const useTemplate = (templateId?: string) => {
- const template = useMemo(() => {
- return templatesList.find((template) => template.id === templateId);
- }, [templateId]);
-
- if (!template || !template.Component) return null;
-
- return template;
-};
diff --git a/libs/hooks/src/index.ts b/libs/hooks/src/index.ts
index 615d124b3..9e33af740 100644
--- a/libs/hooks/src/index.ts
+++ b/libs/hooks/src/index.ts
@@ -1,5 +1,4 @@
export * from "./hooks/use-breakpoint";
export * from "./hooks/use-form-field";
export * from "./hooks/use-password-toggle";
-export * from "./hooks/use-template";
export * from "./hooks/use-theme";
diff --git a/libs/schema/src/index.ts b/libs/schema/src/index.ts
index d8f9c42c7..9c3c58eb6 100644
--- a/libs/schema/src/index.ts
+++ b/libs/schema/src/index.ts
@@ -23,5 +23,6 @@ export const defaultResumeData: ResumeData = {
export * from "./basics";
export * from "./metadata";
+export * from "./sample";
export * from "./sections";
export * from "./shared";
diff --git a/apps/client/src/constants/sample-resume.ts b/libs/schema/src/sample.ts
similarity index 93%
rename from apps/client/src/constants/sample-resume.ts
rename to libs/schema/src/sample.ts
index 90381aab1..205a252b3 100644
--- a/apps/client/src/constants/sample-resume.ts
+++ b/libs/schema/src/sample.ts
@@ -1,4 +1,4 @@
-import { ResumeData } from "@reactive-resume/schema";
+import { ResumeData } from ".";
export const sampleResume: ResumeData = {
basics: {
@@ -13,7 +13,7 @@ export const sampleResume: ResumeData = {
},
customFields: [],
picture: {
- url: "http://localhost:9000/reactive-resume/clomqcm7b0004xi96goz2gqmt/pictures/clomqcm7b0004xi96goz2gqmt.jpg",
+ url: "https://res.cloudinary.com/amruth-pillai/image/upload/v1699362669/reactive-resume/sample-resume/sample-picture_iitowc.jpg",
size: 64,
aspectRatio: 0.75,
borderRadius: 6,
@@ -31,19 +31,19 @@ export const sampleResume: ResumeData = {
visible: true,
id: "summary",
content:
- "With over two decades of experience at the forefront of digital asset financial technology (FinTech) integration across the entire spectrum of financial service company operations, I bring a strategic and analytical approach, underpinned by a deep understanding of cryptocurrency markets, digital asset financial management, compliance, and regulatory frameworks.
Career Highlights
I have a proven track record in the design and deployment of bespoke trading platforms tailored to the unique needs of clients and independent financial entities, exemplified by driving a remarkable 1,200% increase in Assets Under Management (AUM) for Mesirow Financial Holdings, Inc.
Recognized for exceptional leadership abilities, I have consistently cultivated high-performance trading and software engineering teams, achieving retention rates that surpass industry standards.
Demonstrated innovation and thought leadership by co-creating and introducing Telcoin's stablecoin concept to key stakeholders within the banking industry.
Instrumental in advancing Telcoin’s strategic legislative initiatives, my direct involvement has been pivotal in the enactment of supportive financial regulations.
",
+ "With over two decades of experience at the forefront of digital asset financial technology (FinTech) integration across the entire spectrum of financial service company operations, I bring a strategic and analytical approach, underpinned by a deep understanding of cryptocurrency markets, digital asset financial management, compliance, and regulatory frameworks.
Career Highlights
I have a proven track record in the design and deployment of bespoke trading platforms tailored to the unique needs of clients and independent financial entities, exemplified by driving a remarkable 1,200% increase in Assets Under Management (AUM) for Mesirow Financial Holdings, Inc.
Recognized for exceptional leadership abilities, I have consistently cultivated high-performance trading and software engineering teams, achieving retention rates that surpass industry standards.
Instrumental in advancing Telcoin’s strategic legislative initiatives, my direct involvement has been pivotal in the enactment of supportive financial regulations.
",
},
awards: {
name: "Awards",
- columns: 1,
+ columns: 2,
visible: true,
id: "awards",
items: [
{
id: "xk8q4bsp3vdlixehddifqsej",
visible: true,
- title: 'Presented "Current Landscape of Digital Assets and Cryptocurrency"',
- awarder: "Meeting of the Midwest International Trade Association",
+ title: "Current Landscape of Digital Assets",
+ awarder: "Midwest International Trade Association",
date: "Jul 2022",
summary: "",
url: {
@@ -204,7 +204,7 @@ export const sampleResume: ResumeData = {
},
languages: {
name: "Languages",
- columns: 4,
+ columns: 2,
visible: true,
id: "languages",
items: [
@@ -361,7 +361,7 @@ export const sampleResume: ResumeData = {
},
skills: {
name: "Skills",
- columns: 2,
+ columns: 1,
visible: true,
id: "skills",
items: [
@@ -440,7 +440,7 @@ export const sampleResume: ResumeData = {
date: "Jan 2018 - Jul 2020",
location: "Nassau, Bahamas",
summary:
- "Proprietary quantitative trading firm and privately-held quantitative futures fund with $1B in AUM and a focus on futures and OTC FX opportunities. 25+ year track record of trading global derivatives markets.
Execution Team Manager
Led international OTC FX and futures trading desk, software development, compliance, and market data for fund averaging $5B in monthly FX transactions and generating 500K+ futures contracts per month.
Steered a 12-member team of 4 traders and 8 software engineers. Oversaw co-located trade execution and managed direct market access in 4 data centers globally for exchanges not co-located. Built partnerships with trading technology providers. Point of contact with banks, brokerages, FXSpotStream, and 9 other liquidity providers. Led market data feed agreements with exchanges. Maintained CME and Eurex exchange memberships. Headed fulfillment of regulatory compliance and due diligence requests.
Streamlined market data contracts and reduced costs by improving data quality and availability. Consolidated technology providers (Bloomberg and Reuters) and enhanced data collection for time periods needed, data types, and breadth of data.
Scaled capabilities by recruiting to enlarge the team, hiring 3 traders, 2 software engineers, and a consultant with 85% retention for 2+ years. Sourced top talent by posting jobs, leveraging network of contacts, and outsourcing with recruiters.
Reduced bank, vendor, and futures broker fees, expanded access to services, and maintained open lines of communication by strengthening existing relationships. Contacted sales representatives to facilitate introductions.
",
+ "Proprietary quantitative trading firm and privately-held quantitative futures fund with $1B in AUM and a focus on futures and OTC FX opportunities. 25+ year track record of trading global derivatives markets.
Execution Team Manager
Led international OTC FX and futures trading desk, software development, compliance, and market data for fund averaging $5B in monthly FX transactions and generating 500K+ futures contracts per month.
Steered a 12-member team of 4 traders and 8 software engineers. Oversaw co-located trade execution and managed direct market access in 4 data centers globally for exchanges not co-located. Built partnerships with trading technology providers. Point of contact with banks, brokerages, FXSpotStream, and 9 other liquidity providers. Led market data feed agreements with exchanges. Maintained CME and Eurex exchange memberships. Headed fulfillment of regulatory compliance and due diligence requests.
Streamlined market data contracts and reduced costs by improving data quality and availability. Consolidated technology providers (Bloomberg and Reuters) and enhanced data collection for time periods needed, data types, and breadth of data.
Scaled capabilities by recruiting to enlarge the team, hiring 3 traders, 2 software engineers, and a consultant with 85% retention for 2+ years. Sourced top talent by posting jobs, leveraging network of contacts, and outsourcing with recruiters.
Reduced bank, vendor, and futures broker fees, expanded access to services, and maintained open lines of communication by strengthening existing relationships. Contacted sales representatives to facilitate introductions.
",
keywords: [],
url: {
label: "",
@@ -456,7 +456,7 @@ export const sampleResume: ResumeData = {
template: "rhyhorn",
layout: [
[["profiles", "summary", "experience"], []],
- [["custom.juryi0w9w9jabsgorks0bixq", "education", "awards", "certifications"], []],
+ [["custom.juryi0w9w9jabsgorks0bixq", "education", "certifications", "awards"], []],
[
["skills", "interests", "publications", "volunteer", "languages", "projects", "references"],
[],
@@ -477,7 +477,7 @@ export const sampleResume: ResumeData = {
theme: {
background: "#ffffff",
text: "#000000",
- primary: "#222222",
+ primary: "#78716c",
},
typography: {
font: {
diff --git a/libs/templates/.babelrc b/libs/templates/.babelrc
deleted file mode 100644
index e6db86373..000000000
--- a/libs/templates/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": [["@nx/react/babel", { "runtime": "automatic", "useBuiltIns": "usage" }]],
- "plugins": [["styled-components", { "pure": true, "ssr": false }]]
-}
diff --git a/libs/templates/.eslintrc.json b/libs/templates/.eslintrc.json
deleted file mode 100644
index a39ac5d05..000000000
--- a/libs/templates/.eslintrc.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "extends": ["plugin:@nx/react", "../../.eslintrc.json"],
- "ignorePatterns": ["!**/*"],
- "overrides": [
- {
- "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
- "rules": {}
- },
- {
- "files": ["*.ts", "*.tsx"],
- "rules": {}
- },
- {
- "files": ["*.js", "*.jsx"],
- "rules": {}
- }
- ]
-}
diff --git a/libs/templates/package.json b/libs/templates/package.json
deleted file mode 100644
index af9176a29..000000000
--- a/libs/templates/package.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "@reactive-resume/templates",
- "version": "0.0.1",
- "private": false,
- "main": "./index.js",
- "types": "./index.d.ts",
- "publishConfig": {
- "access": "public"
- },
- "exports": {
- ".": {
- "import": "./index.mjs",
- "require": "./index.js"
- }
- }
-}
diff --git a/libs/templates/project.json b/libs/templates/project.json
deleted file mode 100644
index eaef0c37f..000000000
--- a/libs/templates/project.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "templates",
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
- "sourceRoot": "libs/templates/src",
- "projectType": "library",
- "tags": ["frontend"],
- "targets": {
- "lint": {
- "executor": "@nx/eslint:lint",
- "outputs": ["{options.outputFile}"],
- "options": {
- "lintFilePatterns": ["libs/templates/**/*.{ts,tsx,js,jsx}"]
- }
- },
- "build": {
- "executor": "@nx/vite:build",
- "outputs": ["{options.outputPath}"],
- "defaultConfiguration": "production",
- "options": {
- "outputPath": "dist/libs/templates"
- },
- "configurations": {
- "development": {
- "mode": "development"
- },
- "production": {
- "mode": "production"
- }
- }
- },
- "test": {
- "executor": "@nx/vite:test",
- "outputs": ["{options.reportsDirectory}"],
- "options": {
- "passWithNoTests": true,
- "reportsDirectory": "../../coverage/libs/templates"
- }
- }
- }
-}
diff --git a/libs/templates/src/index.ts b/libs/templates/src/index.ts
deleted file mode 100644
index 10ec82f4e..000000000
--- a/libs/templates/src/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from "./shared";
-export * from "./styles";
-export * from "./templates";
diff --git a/libs/templates/src/shared/artboard.tsx b/libs/templates/src/shared/artboard.tsx
deleted file mode 100644
index 2467dc7ee..000000000
--- a/libs/templates/src/shared/artboard.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import { ResumeData } from "@reactive-resume/schema";
-import { useEffect, useMemo } from "react";
-import { FrameContextConsumer } from "react-frame-component";
-import { StyleSheetManager } from "styled-components";
-
-import { GlobalStyles } from "../styles";
-import { GlobalStyleProps } from "../styles/shared";
-import { FrameWrapper } from "./frame";
-import { useStore } from "./store";
-
-type Props = {
- resume: ResumeData;
- children: React.ReactNode;
- style?: React.CSSProperties;
-};
-
-export const Artboard = ({ resume, style, children }: Props) => {
- const store = useStore();
- const metadata = useStore((state) => state.metadata);
-
- const styles: GlobalStyleProps | null = useMemo(() => {
- if (!metadata) return null;
-
- return {
- $css: metadata.css,
- $page: metadata.page,
- $theme: metadata.theme,
- $typography: metadata.typography,
- };
- }, [metadata]);
-
- useEffect(() => useStore.setState(resume), [resume]);
-
- if (Object.keys(store).length === 0 || !styles) return;
-
- return (
-
-
- {({ document }) => (
-
-
-
- {children}
-
- )}
-
-
- );
-};
diff --git a/libs/templates/src/shared/frame.tsx b/libs/templates/src/shared/frame.tsx
deleted file mode 100644
index aa983dded..000000000
--- a/libs/templates/src/shared/frame.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import { pageSizeMap } from "@reactive-resume/utils";
-import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
-import Frame from "react-frame-component";
-import webfontloader from "webfontloader";
-
-import { useStore } from "./store";
-
-type Props = {
- children: React.ReactNode;
- style?: React.CSSProperties;
-};
-
-export const FrameWrapper = ({ children, style }: Props) => {
- const resume = useStore();
- const format = resume.metadata.page.format;
- const font = resume.metadata.typography.font;
-
- const fontString = useMemo(() => {
- const family = font.family;
- const variants = font.variants.join(",");
- const subset = font.subset;
-
- return `${family}:${variants}:${subset}`;
- }, [font]);
-
- const frameRef = useRef(null);
-
- const width = useMemo(() => `${pageSizeMap[format].width}mm`, [format]);
- const [height, setHeight] = useState(`${pageSizeMap[format].height}mm`);
-
- const handleResize = useCallback((frame: HTMLIFrameElement) => {
- const height = frame.contentDocument?.body?.scrollHeight ?? 0;
- setHeight(`${height}px`);
- }, []);
-
- const loadFonts = useCallback(
- (frame: HTMLIFrameElement) => {
- if (font.family === "CMU Serif") {
- return webfontloader.load({
- classes: false,
- custom: {
- families: ["CMU Serif"],
- urls: ["https://cdn.jsdelivr.net/npm/computer-modern/cmu-serif.min.css"],
- },
- context: frame.contentWindow!,
- fontactive: () => handleResize(frame!),
- });
- }
-
- webfontloader.load({
- classes: false,
- google: { families: [fontString] },
- context: frame.contentWindow!,
- fontactive: () => handleResize(frame!),
- });
- },
- [font, fontString, handleResize],
- );
-
- const loadIconFonts = useCallback((frame: HTMLIFrameElement) => {
- const document = frame.contentDocument!;
-
- const link = document.createElement("link");
- link.type = "text/css";
- link.rel = "stylesheet";
- link.href = "https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css";
-
- document.head.appendChild(link);
- }, []);
-
- const onLoad = useCallback(() => {
- if (!frameRef.current) return;
-
- handleResize(frameRef.current);
- loadFonts(frameRef.current);
- loadIconFonts(frameRef.current);
- }, [frameRef, handleResize, loadFonts, loadIconFonts]);
-
- useEffect(() => {
- onLoad();
- }, [resume, onLoad]);
-
- useEffect(() => {
- setTimeout(onLoad, 250);
- }, [onLoad]);
-
- return (
-
- {children}
-
- );
-};
diff --git a/libs/templates/src/shared/index.ts b/libs/templates/src/shared/index.ts
deleted file mode 100644
index 330cdb144..000000000
--- a/libs/templates/src/shared/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from "./artboard";
-export * from "./frame";
-export * from "./store";
-export * from "./templates";
diff --git a/libs/templates/src/shared/store.ts b/libs/templates/src/shared/store.ts
deleted file mode 100644
index c0d1bde5a..000000000
--- a/libs/templates/src/shared/store.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { ResumeData } from "@reactive-resume/schema";
-import { create } from "zustand";
-
-export const useStore = create()(() => ({}) as ResumeData);
diff --git a/libs/templates/src/styles/grid.ts b/libs/templates/src/styles/grid.ts
deleted file mode 100644
index f310bb3a2..000000000
--- a/libs/templates/src/styles/grid.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import styled from "styled-components";
-
-export const ItemGrid = styled.div<{ $columns?: number }>`
- display: grid;
- grid-gap: 16px;
- grid-template-columns: repeat(${({ $columns }) => $columns ?? 1}, 1fr);
-`;
-
-export const PageGrid = styled.div<{ $offset: number }>`
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- column-gap: ${({ $offset }) => $offset}px;
-`;
diff --git a/libs/templates/src/styles/index.tsx b/libs/templates/src/styles/index.tsx
deleted file mode 100644
index f10fcbf01..000000000
--- a/libs/templates/src/styles/index.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { createGlobalStyle } from "styled-components";
-
-import { Reset } from "./reset";
-import { GlobalStyleProps, Shared } from "./shared";
-
-export const GlobalStyles = createGlobalStyle`
- ${Reset}
- ${Shared}
-`;
-
-export * from "./grid";
-export * from "./page";
-export * from "./picture";
diff --git a/libs/templates/src/styles/page.ts b/libs/templates/src/styles/page.ts
deleted file mode 100644
index b202c9f4d..000000000
--- a/libs/templates/src/styles/page.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import styled from "styled-components";
-
-export const PageWrapper = styled.div`
- position: relative;
-
- width: var(--page-width);
- padding: var(--page-margin);
- min-height: var(--page-height);
-
- /* Theme */
- color: var(--color-text);
- background-color: var(--color-background);
-
- @media print {
- margin: 0 auto;
-
- &:not(:last-child) {
- height: var(--page-height);
- }
- }
-`;
-
-export const PageNumber = styled.p`
- top: 0;
- right: 0;
- color: black;
- font-size: 12px;
- font-weight: 600;
- padding: 0 0.5rem;
- position: absolute;
- outline: 1px solid black;
- background-color: white;
-`;
-
-export const PageBreakLine = styled.div<{ $pageHeight: number }>`
- position: absolute;
- top: ${({ $pageHeight }) => $pageHeight}mm;
- left: 0;
- right: 0;
- z-index: 10;
- border: 1px dashed var(--color-text);
-
- /* Text */
- &:before {
- content: "End of Page";
- background: white;
- color: black;
- display: block;
- font-size: 12px;
- font-weight: 600;
- height: auto;
- line-height: 0rem;
- padding: 12px 16px;
- position: absolute;
- right: 0;
- text-align: right;
- top: -25px;
- }
-`;
diff --git a/libs/templates/src/styles/picture.ts b/libs/templates/src/styles/picture.ts
deleted file mode 100644
index cc9e8315d..000000000
--- a/libs/templates/src/styles/picture.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Basics } from "@reactive-resume/schema";
-import styled from "styled-components";
-
-export const Picture = styled.img<{ $picture: Basics["picture"] }>`
- width: ${({ $picture }) => $picture.size}px;
- aspect-ratio: ${({ $picture }) => $picture.aspectRatio};
- border-radius: ${({ $picture }) => $picture.borderRadius}px;
-
- ${({ $picture }) => $picture.effects.grayscale && `filter: grayscale(1);`}
- ${({ $picture }) => $picture.effects.border && `border: 2px solid var(--color-primary);`}
-`;
diff --git a/libs/templates/src/styles/reset.ts b/libs/templates/src/styles/reset.ts
deleted file mode 100644
index 1b7d16352..000000000
--- a/libs/templates/src/styles/reset.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import { css } from "styled-components";
-
-export const Reset = css`
- /***
- The new CSS reset - version 1.11.1 (last updated 24.10.2023)
- GitHub page: https://github.com/elad2412/the-new-css-reset
- ***/
-
- /*
- Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property
- - The "symbol *" part is to solve Firefox SVG sprite bug
- - The "html" element is excluded, otherwise a bug in Chrome breaks the CSS hyphens property (https://github.com/elad2412/the-new-css-reset/issues/36)
- */
- *:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) {
- all: unset;
- display: revert;
- }
-
- /* Preferred box-sizing value */
- *,
- *::before,
- *::after {
- box-sizing: border-box;
- }
-
- /* Fix mobile Safari increase font-size on landscape mode */
- html {
- -moz-text-size-adjust: none;
- -webkit-text-size-adjust: none;
- text-size-adjust: none;
- font-size: var(--font-size);
- font-family: var(--font-family);
- }
-
- body {
- overflow: hidden;
- }
-
- /* Reapply the pointer cursor for anchor tags */
- a,
- button {
- cursor: revert;
- }
-
- /* Remove list styles (bullets/numbers) */
- ol,
- ul,
- menu,
- summary {
- list-style: none;
- }
-
- /* For images to not be able to exceed their container */
- img {
- max-inline-size: 100%;
- max-block-size: 100%;
- }
-
- /* removes spacing between cells in tables */
- table {
- border-collapse: collapse;
- }
-
- /* Safari - solving issue when using user-select:none on the text input doesn't working */
- input,
- textarea {
- user-select: auto;
- -webkit-user-select: auto;
- }
-
- /* revert the 'white-space' property for textarea elements on Safari */
- textarea {
- white-space: revert;
- }
-
- /* minimum style to allow to style meter element */
- meter {
- -webkit-appearance: revert;
- appearance: revert;
- }
-
- /* preformatted text - use only for this feature */
- :where(pre) {
- all: revert;
- box-sizing: border-box;
- }
-
- /* reset default text opacity of input placeholder */
- ::placeholder {
- color: unset;
- }
-
- /* fix the feature of 'hidden' attribute.
- display:revert; revert to element instead of attribute */
- :where([hidden]) {
- display: none;
- }
-
- /* revert for bug in Chromium browsers
- - fix for the content editable attribute will work properly.
- - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/
- :where([contenteditable]:not([contenteditable="false"])) {
- -moz-user-modify: read-write;
- -webkit-user-modify: read-write;
- overflow-wrap: break-word;
- line-break: after-white-space;
- -webkit-line-break: after-white-space;
- user-select: auto;
- -webkit-user-select: auto;
- }
-
- /* apply back the draggable feature - exist only in Chromium and Safari */
- :where([draggable="true"]) {
- -webkit-user-drag: element;
- }
-
- /* Revert Modal native behavior */
- :where(dialog:modal) {
- all: revert;
- box-sizing: border-box;
- }
-`;
diff --git a/libs/templates/src/styles/shared.ts b/libs/templates/src/styles/shared.ts
deleted file mode 100644
index a29408355..000000000
--- a/libs/templates/src/styles/shared.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-import { Metadata } from "@reactive-resume/schema";
-import { pageSizeMap } from "@reactive-resume/utils";
-import { css } from "styled-components";
-
-export type GlobalStyleProps = {
- $css: Metadata["css"];
- $page: Metadata["page"];
- $theme: Metadata["theme"];
- $typography: Metadata["typography"];
-};
-
-export const Shared = css`
- /* CSS Variables */
- :root {
- /* Theme */
- --color-text: ${({ $theme }) => $theme.text};
- --color-primary: ${({ $theme }) => $theme.primary};
- --color-background: ${({ $theme }) => $theme.background};
-
- /* Page */
- --page-width: ${({ $page }) => pageSizeMap[$page.format].width}mm;
- --page-height: ${({ $page }) => pageSizeMap[$page.format].height}mm;
- --page-margin: ${({ $page }) => $page.margin}px;
-
- /* Typography */
- --font-size: ${({ $typography }) => $typography.font.size}px;
- --font-family: ${({ $typography }) => $typography.font.family};
- --line-height: ${({ $typography }) => $typography.lineHeight}rem;
- }
-
- /* Headings */
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- font-weight: bold;
- line-height: var(--line-height);
- }
-
- h1 {
- font-size: 2rem;
- }
-
- h2 {
- font-size: 1.5rem;
- }
-
- h3 {
- font-size: 1rem;
- }
-
- /* Paragraphs */
- p {
- font-size: var(--font-size);
- line-height: var(--line-height);
- }
-
- b,
- strong {
- font-weight: bold;
- }
-
- small {
- font-size: calc(var(--font-size) - 2px);
- line-height: calc(var(--line-height) - 2px);
- }
-
- i,
- em {
- font-style: italic;
- }
-
- u {
- text-decoration: underline;
- text-underline-offset: 1.5px;
- }
-
- a {
- text-decoration: ${({ $typography }) => ($typography.underlineLinks ? "underline" : "none")};
- text-underline-offset: 1.5px;
- }
-
- s,
- del {
- text-decoration: line-through;
- }
-
- pre,
- code {
- font-family: monospace;
- }
-
- pre code {
- display: block;
- padding: 1rem;
- border-radius: 4px;
- color: white;
- background-color: black;
- }
-
- mark {
- color: black;
- background-color: #fcd34d;
- }
-
- /* Lists */
- menu,
- ol,
- ul {
- list-style: disc inside;
-
- li {
- margin: 0.25rem 0;
- line-height: var(--line-height);
-
- p {
- display: inline;
- line-height: var(--line-height);
- }
- }
-
- menu,
- ol,
- ul {
- list-style: circle inside;
-
- li {
- padding-left: 32px;
- }
- }
- }
-
- /* Horizontal Rules */
- hr {
- margin: 0.5rem 0;
- border: 0.5px solid currentColor;
- }
-
- /* Images */
- img {
- display: block;
- max-width: 100%;
- object-fit: cover;
- }
-`;
diff --git a/libs/templates/src/templates/index.ts b/libs/templates/src/templates/index.ts
deleted file mode 100644
index 9ef61b7fc..000000000
--- a/libs/templates/src/templates/index.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { TemplateProps } from "../shared";
-import { Rhyhorn } from "./rhyhorn";
-
-type Template = {
- id: string;
- name: string;
- Component: (props: TemplateProps) => JSX.Element;
-};
-
-export const templatesList: Template[] = [
- {
- id: "rhyhorn",
- name: "Rhyhorn",
- Component: Rhyhorn,
- },
-];
diff --git a/libs/templates/src/templates/rhyhorn/index.tsx b/libs/templates/src/templates/rhyhorn/index.tsx
deleted file mode 100644
index acfd764fd..000000000
--- a/libs/templates/src/templates/rhyhorn/index.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { SectionKey } from "@reactive-resume/schema";
-
-import { TemplateProps } from "../../shared";
-import { Awards } from "./sections/awards";
-import { Certifications } from "./sections/certifications";
-import { CustomSection } from "./sections/custom";
-import { Education } from "./sections/education";
-import { Experience } from "./sections/experience";
-import { Header } from "./sections/header";
-import { Interests } from "./sections/interests";
-import { Languages } from "./sections/languages";
-import { Profiles } from "./sections/profiles";
-import { Projects } from "./sections/projects";
-import { Publications } from "./sections/publications";
-import { References } from "./sections/references";
-import { Skills } from "./sections/skills";
-import { Summary } from "./sections/summary";
-import { Volunteer } from "./sections/volunteer";
-import { RhyhornWrapper } from "./style";
-
-const sectionMap: Partial React.ReactNode>> = {
- summary: Summary,
- profiles: Profiles,
- experience: Experience,
- education: Education,
- awards: Awards,
- skills: Skills,
- certifications: Certifications,
- interests: Interests,
- languages: Languages,
- volunteer: Volunteer,
- projects: Projects,
- publications: Publications,
- references: References,
-};
-
-const getSection = (id: SectionKey) => {
- const Section = sectionMap[id];
-
- // Custom Section
- if (!Section) return ;
-
- return ;
-};
-
-export const Rhyhorn = ({ isFirstPage, columns }: TemplateProps) => (
-
- {isFirstPage && }
-
- {/* Main */}
- {columns[0].map(getSection)}
-
- {/* Sidebar */}
- {columns[1].map(getSection)}
-
-);
diff --git a/libs/templates/src/templates/rhyhorn/sections/awards.tsx b/libs/templates/src/templates/rhyhorn/sections/awards.tsx
deleted file mode 100644
index 521f7a2e7..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/awards.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Award as IAward } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Awards = () => {
- const section = useStore((state) => state.sections.awards);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.title}
-
{item.awarder}
-
-
-
-
{item.date}
-
- >
- )}
- main={(item) => }
- footer={(item) => (
-
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/certifications.tsx b/libs/templates/src/templates/rhyhorn/sections/certifications.tsx
deleted file mode 100644
index ef5f26f8c..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/certifications.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Certification as ICertification } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Certifications = () => {
- const section = useStore((state) => state.sections.certifications);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.name}
-
{item.issuer}
-
-
-
-
{item.date}
-
- >
- )}
- main={(item) => }
- footer={(item) => (
-
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/custom.tsx b/libs/templates/src/templates/rhyhorn/sections/custom.tsx
deleted file mode 100644
index 70012015b..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/custom.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import {
- CustomSection as ICustomSection,
- CustomSectionItem,
- SectionKey,
-} from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-import get from "lodash.get";
-
-import { SectionBase } from "../shared/section-base";
-
-type Props = {
- id: SectionKey;
-};
-
-export const CustomSection = ({ id }: Props) => {
- const section = useStore((state) => get(state.sections, id));
-
- if (!section) return null;
-
- return (
- // @ts-expect-error Unable to infer type of Custom Section accurately, ignoring for now
-
- section={section}
- header={(item: CustomSectionItem) => (
- <>
-
-
{item.name}
-
{item.description}
-
-
-
-
{item.date}
-
{item.location}
-
- >
- )}
- main={(item: CustomSectionItem) => }
- footer={(item: CustomSectionItem) => (
- <>
- {item.keywords.join(", ")}
-
-
- >
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/education.tsx b/libs/templates/src/templates/rhyhorn/sections/education.tsx
deleted file mode 100644
index 05902286f..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/education.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Education as IEducation } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Education = () => {
- const section = useStore((state) => state.sections.education);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.institution}
-
{item.area}
-
-
-
-
{item.date}
-
- {item.studyType}
- {item.score ? ` | ${item.score}` : ""}
-
-
- >
- )}
- main={(item) => }
- footer={(item) => (
-
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/experience.tsx b/libs/templates/src/templates/rhyhorn/sections/experience.tsx
deleted file mode 100644
index 9b52908fa..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/experience.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Experience as IExperience } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Experience = () => {
- const section = useStore((state) => state.sections.experience);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.company}
-
{item.position}
-
-
-
-
{item.date}
-
{item.location}
-
- >
- )}
- main={(item) => }
- footer={(item) => (
-
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/header.tsx b/libs/templates/src/templates/rhyhorn/sections/header.tsx
deleted file mode 100644
index 8a10bfd0b..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/header.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import { Picture, useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-export const Header = () => {
- const basics = useStore((state) => state.basics);
-
- return (
-
- {isUrl(basics.picture.url) && !basics.picture.effects.hidden && (
-
- )}
-
-
-
{basics.name}
-
{basics.headline}
-
-
-
-
- {basics.customFields.map((field) => (
-
- {[field.name, field.value].filter(Boolean).join(": ")}
-
- ))}
-
-
-
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/interests.tsx b/libs/templates/src/templates/rhyhorn/sections/interests.tsx
deleted file mode 100644
index 5f54f5f92..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/interests.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { Interest as IInterest } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Interests = () => {
- const section = useStore((state) => state.sections.interests);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.name}
-
{item.keywords.join(", ")}
-
-
-
- >
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/languages.tsx b/libs/templates/src/templates/rhyhorn/sections/languages.tsx
deleted file mode 100644
index dfa355d53..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/languages.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Language as ILanguage } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { getCEFRLevel } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Languages = () => {
- const section = useStore((state) => state.sections.languages);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.name}
-
{item.fluency || getCEFRLevel(item.fluencyLevel)}
-
-
-
- >
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/profiles.tsx b/libs/templates/src/templates/rhyhorn/sections/profiles.tsx
deleted file mode 100644
index 3f4b530b2..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/profiles.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Profile as IProfile } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-import styled from "styled-components";
-
-import { SectionBase } from "../shared/section-base";
-
-const Username = styled.h6`
- line-height: 1;
- font-weight: 500;
-`;
-
-export const Profiles = () => {
- const section = useStore((state) => state.sections.profiles);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
- {item.icon && (
-
-
-
- )}
-
- {isUrl(item.url.href) ? (
-
- {item.username}
-
- ) : (
-
{item.username}
- )}
-
{item.network}
-
-
-
- >
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/projects.tsx b/libs/templates/src/templates/rhyhorn/sections/projects.tsx
deleted file mode 100644
index 3b9c16706..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/projects.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Project as IProject } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Projects = () => {
- const section = useStore((state) => state.sections.projects);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.name}
-
{item.description}
-
-
-
-
{item.date}
-
- >
- )}
- main={(item) => }
- footer={(item) => (
- <>
- {item.keywords.join(", ")}
-
-
- >
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/publications.tsx b/libs/templates/src/templates/rhyhorn/sections/publications.tsx
deleted file mode 100644
index fcb60d276..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/publications.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Publication as IPublication } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Publications = () => {
- const section = useStore((state) => state.sections.publications);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.name}
-
{item.publisher}
-
-
-
-
{item.date}
-
- >
- )}
- main={(item) => }
- footer={(item) => (
-
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/references.tsx b/libs/templates/src/templates/rhyhorn/sections/references.tsx
deleted file mode 100644
index 0db39fa8a..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/references.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Reference as IReference } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const References = () => {
- const section = useStore((state) => state.sections.references);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.name}
-
{item.description}
-
-
-
- >
- )}
- main={(item) => }
- footer={(item) => (
-
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/skills.tsx b/libs/templates/src/templates/rhyhorn/sections/skills.tsx
deleted file mode 100644
index 09462dab9..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/skills.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Skill as ISkill } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Skills = () => {
- const section = useStore((state) => state.sections.skills);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.name}
-
{item.description}
-
-
-
- >
- )}
- footer={(item) => {item.keywords.join(", ")}}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/summary.tsx b/libs/templates/src/templates/rhyhorn/sections/summary.tsx
deleted file mode 100644
index 7d00f35be..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/summary.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { useStore } from "@reactive-resume/templates";
-
-export const Summary = () => {
- const section = useStore((state) => state.sections.summary);
-
- if (!section.visible || !section.content) return null;
-
- return (
-
- {section.name}
-
-
-
-
-
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/sections/volunteer.tsx b/libs/templates/src/templates/rhyhorn/sections/volunteer.tsx
deleted file mode 100644
index 5ac6e5635..000000000
--- a/libs/templates/src/templates/rhyhorn/sections/volunteer.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Volunteer as IVolunteer } from "@reactive-resume/schema";
-import { useStore } from "@reactive-resume/templates";
-import { isUrl } from "@reactive-resume/utils";
-
-import { SectionBase } from "../shared/section-base";
-
-export const Volunteer = () => {
- const section = useStore((state) => state.sections.volunteer);
-
- return (
-
- section={section}
- header={(item) => (
- <>
-
-
{item.organization}
-
{item.position}
-
-
-
-
{item.date}
-
{item.location}
-
- >
- )}
- main={(item) => }
- footer={(item) => (
-
- )}
- />
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/shared/section-base.tsx b/libs/templates/src/templates/rhyhorn/shared/section-base.tsx
deleted file mode 100644
index 0b5a69d34..000000000
--- a/libs/templates/src/templates/rhyhorn/shared/section-base.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Item, SectionItem, SectionWithItem } from "@reactive-resume/schema";
-import { ItemGrid } from "@reactive-resume/templates";
-
-type Props = {
- section: SectionWithItem;
- header?: (item: T) => React.ReactNode;
- main?: (item: T) => React.ReactNode;
- footer?: (item: T) => React.ReactNode;
-};
-
-export const SectionBase = ({ section, header, main, footer }: Props) => {
- if (!section.visible || !section.items.length) return null;
-
- return (
-
- {section.name}
-
-
- {section.items
- .filter((item) => !!item.visible)
- .map((item) => (
-
- {header && }
- {main && {main(item as T)}}
- {footer && }
-
- ))}
-
-
- );
-};
diff --git a/libs/templates/src/templates/rhyhorn/style.ts b/libs/templates/src/templates/rhyhorn/style.ts
deleted file mode 100644
index c94944b60..000000000
--- a/libs/templates/src/templates/rhyhorn/style.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import styled from "styled-components";
-
-export const RhyhornWrapper = styled.div`
- display: grid;
- row-gap: 16px;
-
- .header {
- display: flex;
-
- &__picture {
- align-self: center;
- margin-right: 12px;
- }
-
- &__basics {
- align-self: center;
- }
-
- &__name {
- font-size: 1.5rem;
- line-height: calc(var(--line-height) + 0.5rem);
- }
-
- &__headline {
- color: var(--color-primary);
- }
-
- &__meta {
- font-size: 0.875rem;
- line-height: var(--line-height);
-
- span {
- padding: 0 6px;
- border-right: 1px solid currentColor;
-
- &:first-child {
- padding-left: 0;
- }
-
- &:last-child {
- border-right: none;
- }
- }
- }
- }
-
- .section {
- &__heading {
- font-size: 0.9rem;
- line-height: 1.2rem;
- padding-bottom: 2px;
- margin-bottom: 6px;
- text-transform: uppercase;
- color: var(--color-primary);
- border-bottom: 1px solid var(--color-text);
- }
-
- &__item {
- display: flex;
- flex-direction: column;
- gap: 4px;
-
- &-header {
- position: relative;
- display: flex;
- align-items: flex-start;
- justify-content: space-between;
- gap: 6px;
-
- & > div:last-child {
- text-align: right;
- }
-
- &:has(i) div {
- margin-left: 22px;
- }
-
- & > div > i {
- position: absolute;
- top: 6px;
- left: 0;
- }
- }
-
- &-content p:not(:last-child),
- &-main p:not(:last-child) {
- padding-bottom: 0.75rem;
- }
-
- & .rating {
- display: flex;
- justify-content: flex-end;
- margin-top: 4px;
-
- & > span {
- width: 8px;
- height: 8px;
- margin-left: 4px;
- border-radius: 50%;
- border: 1px solid currentColor;
- }
- }
- }
- }
-`;
diff --git a/libs/templates/tsconfig.spec.json b/libs/templates/tsconfig.spec.json
deleted file mode 100644
index 6a4c53c4f..000000000
--- a/libs/templates/tsconfig.spec.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"]
- },
- "include": [
- "vite.config.ts",
- "src/**/*.test.ts",
- "src/**/*.spec.ts",
- "src/**/*.test.tsx",
- "src/**/*.spec.tsx",
- "src/**/*.test.js",
- "src/**/*.spec.js",
- "src/**/*.test.jsx",
- "src/**/*.spec.jsx",
- "src/**/*.d.ts"
- ]
-}
diff --git a/libs/templates/vite.config.ts b/libs/templates/vite.config.ts
deleted file mode 100644
index 15dd9c0d9..000000000
--- a/libs/templates/vite.config.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-///
-
-import { nxViteTsPaths } from "@nx/vite/plugins/nx-tsconfig-paths.plugin";
-import react from "@vitejs/plugin-react";
-import * as path from "path";
-import { defineConfig } from "vite";
-import dts from "vite-plugin-dts";
-
-export default defineConfig({
- cacheDir: "../../node_modules/.vite/templates",
-
- plugins: [
- react(),
- nxViteTsPaths(),
- dts({
- entryRoot: "src",
- tsconfigPath: path.join(__dirname, "tsconfig.lib.json"),
- }),
- ],
-
- build: {
- lib: {
- entry: "src/index.ts",
- name: "templates",
- fileName: "index",
- formats: ["es", "cjs"],
- },
- rollupOptions: {
- external: ["react", "react-dom", "react/jsx-runtime"],
- },
- },
-
- test: {
- globals: true,
- environment: "jsdom",
- cache: { dir: "../../node_modules/.vitest" },
- include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
- },
-});
diff --git a/libs/ui/src/variants/button.ts b/libs/ui/src/variants/button.ts
index 92b3a0d3f..e0bc89b6c 100644
--- a/libs/ui/src/variants/button.ts
+++ b/libs/ui/src/variants/button.ts
@@ -1,11 +1,7 @@
import { cva } from "class-variance-authority";
export const buttonVariants = cva(
- [
- "inline-flex items-center justify-center rounded-sm text-sm font-medium ring-offset-background disabled:pointer-events-none disabled:opacity-50",
- "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary focus-visible:ring-offset-2",
- "scale-100 transition-[transform,background-color] active:scale-95",
- ],
+ "inline-flex scale-100 items-center justify-center rounded-sm text-sm font-medium ring-offset-background transition-[transform,background-color] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary focus-visible:ring-offset-2 active:scale-95 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
diff --git a/libs/utils/src/namespaces/page.ts b/libs/utils/src/namespaces/page.ts
index 440981501..e190f0744 100644
--- a/libs/utils/src/namespaces/page.ts
+++ b/libs/utils/src/namespaces/page.ts
@@ -1,3 +1,5 @@
+import { Template } from "./types";
+
export const pageSizeMap = {
a4: {
width: 210,
@@ -8,3 +10,12 @@ export const pageSizeMap = {
height: 279,
},
};
+
+export const templatesList: Template[] = [
+ {
+ id: "rhyhorn",
+ name: "Rhyhorn",
+ image:
+ "https://res.cloudinary.com/amruth-pillai/image/upload/v1699370067/reactive-resume/templates/482-2480x3508_vuf5ev.jpg",
+ },
+];
diff --git a/libs/utils/src/namespaces/string.ts b/libs/utils/src/namespaces/string.ts
index ab5fec801..61e702c51 100644
--- a/libs/utils/src/namespaces/string.ts
+++ b/libs/utils/src/namespaces/string.ts
@@ -15,6 +15,11 @@ export const isUrl = (string: string) => {
return urlRegex.test(string);
};
+export const isEmptyString = (string: string) => {
+ if (string === "") return true;
+ return string.trim().length === 0;
+};
+
export const extractUrl = (string: string) => {
const urlRegex = /https?:\/\/[^ \n]+/i;
diff --git a/libs/utils/src/namespaces/types.ts b/libs/utils/src/namespaces/types.ts
index 252ed85b4..1e468c097 100644
--- a/libs/utils/src/namespaces/types.ts
+++ b/libs/utils/src/namespaces/types.ts
@@ -1,5 +1,7 @@
export type Json = Record;
+export type Template = { id: string; name: string; image: string };
+
export type LayoutLocator = { page: number; column: number; section: number };
export type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T;
diff --git a/package.json b/package.json
index 20d7c5c4d..77c721232 100644
--- a/package.json
+++ b/package.json
@@ -51,28 +51,27 @@
"@tailwindcss/typography": "^0.5.10",
"@tanstack/eslint-plugin-query": "^5.6.0",
"@testing-library/react": "14.0.0",
- "@types/async-retry": "^1.4.7",
- "@types/bcryptjs": "^2.4.5",
- "@types/cookie-parser": "^1.4.5",
- "@types/express": "^4.17.20",
- "@types/file-saver": "^2.0.6",
+ "@types/async-retry": "^1.4.8",
+ "@types/bcryptjs": "^2.4.6",
+ "@types/cookie-parser": "^1.4.6",
+ "@types/express": "^4.17.21",
+ "@types/file-saver": "^2.0.7",
"@types/jest": "^29.5.7",
- "@types/lodash.debounce": "^4.0.8",
- "@types/lodash.get": "^4.4.8",
- "@types/lodash.set": "^4.3.8",
- "@types/multer": "^1.4.9",
+ "@types/lodash.debounce": "^4.0.9",
+ "@types/lodash.get": "^4.4.9",
+ "@types/lodash.set": "^4.3.9",
+ "@types/multer": "^1.4.10",
"@types/node": "20.8.10",
"@types/nodemailer": "^6.4.13",
- "@types/papaparse": "^5.3.10",
- "@types/passport": "^1.0.14",
- "@types/passport-github2": "^1.2.8",
- "@types/passport-google-oauth20": "^2.0.13",
- "@types/passport-local": "^1.0.37",
+ "@types/papaparse": "^5.3.11",
+ "@types/passport": "^1.0.15",
+ "@types/passport-github2": "^1.2.9",
+ "@types/passport-google-oauth20": "^2.0.14",
+ "@types/passport-local": "^1.0.38",
"@types/react": "18.2.36",
"@types/react-dom": "18.2.14",
"@types/react-is": "18.2.3",
"@types/retry": "^0.12.4",
- "@types/styled-components": "5.1.29",
"@types/webfontloader": "^1.6.36",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
@@ -81,7 +80,6 @@
"@vitest/coverage-v8": "^0.34.6",
"@vitest/ui": "~0.34.6",
"autoprefixer": "^10.4.16",
- "babel-plugin-styled-components": "2.1.4",
"cypress": "^13.4.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "~8.53.0",
@@ -115,10 +113,10 @@
"vitest": "~0.34.6"
},
"dependencies": {
- "@dnd-kit/core": "^6.0.8",
- "@dnd-kit/modifiers": "^6.0.1",
- "@dnd-kit/sortable": "^7.0.2",
- "@dnd-kit/utilities": "^3.2.1",
+ "@dnd-kit/core": "^6.1.0",
+ "@dnd-kit/modifiers": "^7.0.0",
+ "@dnd-kit/sortable": "^8.0.0",
+ "@dnd-kit/utilities": "^3.2.2",
"@fontsource/ibm-plex-sans": "^5.0.17",
"@hookform/resolvers": "^3.3.2",
"@nestjs-modules/mailer": "^1.9.1",
@@ -172,7 +170,7 @@
"@tiptap/extension-underline": "^2.1.12",
"@tiptap/react": "^2.1.12",
"@tiptap/starter-kit": "^2.1.12",
- "@types/passport-jwt": "^3.0.12",
+ "@types/passport-jwt": "^3.0.13",
"async-retry": "^1.3.3",
"await-to-js": "^3.0.0",
"axios": "^1.6.0",
@@ -188,7 +186,7 @@
"deepmerge": "^4.3.1",
"file-saver": "^2.0.5",
"framer-motion": "^10.16.4",
- "helmet": "^7.0.0",
+ "helmet": "^7.1.0",
"immer": "^10.0.3",
"ioredis": "^5.3.2",
"jszip": "^3.10.1",
@@ -201,7 +199,7 @@
"nestjs-prisma": "^0.22.0",
"nestjs-zod": "^3.0.0",
"nodemailer": "^6.9.7",
- "openai": "^4.16.0",
+ "openai": "^4.16.1",
"otplib": "^12.0.1",
"papaparse": "^5.4.1",
"passport": "^0.6.0",
@@ -215,10 +213,8 @@
"react": "18.2.0",
"react-colorful": "^5.6.1",
"react-dom": "18.2.0",
- "react-frame-component": "^5.2.6",
"react-helmet-async": "^1.3.0",
"react-hook-form": "^7.48.2",
- "react-is": "18.2.0",
"react-parallax-tilt": "^1.7.172",
"react-resizable-panels": "^0.0.55",
"react-router-dom": "6.18.0",
@@ -226,7 +222,6 @@
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"sharp": "^0.32.6",
- "styled-components": "6.1.0",
"tailwind-merge": "^2.0.0",
"tslib": "^2.6.2",
"unique-names-generator": "^4.7.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 650d88e04..4f866a638 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,17 +6,17 @@ settings:
dependencies:
'@dnd-kit/core':
- specifier: ^6.0.8
- version: 6.0.8(react-dom@18.2.0)(react@18.2.0)
+ specifier: ^6.1.0
+ version: 6.1.0(react-dom@18.2.0)(react@18.2.0)
'@dnd-kit/modifiers':
- specifier: ^6.0.1
- version: 6.0.1(@dnd-kit/core@6.0.8)(react@18.2.0)
+ specifier: ^7.0.0
+ version: 7.0.0(@dnd-kit/core@6.1.0)(react@18.2.0)
'@dnd-kit/sortable':
- specifier: ^7.0.2
- version: 7.0.2(@dnd-kit/core@6.0.8)(react@18.2.0)
+ specifier: ^8.0.0
+ version: 8.0.0(@dnd-kit/core@6.1.0)(react@18.2.0)
'@dnd-kit/utilities':
- specifier: ^3.2.1
- version: 3.2.1(react@18.2.0)
+ specifier: ^3.2.2
+ version: 3.2.2(react@18.2.0)
'@fontsource/ibm-plex-sans':
specifier: ^5.0.17
version: 5.0.17
@@ -177,8 +177,8 @@ dependencies:
specifier: ^2.1.12
version: 2.1.12(@tiptap/pm@2.1.12)
'@types/passport-jwt':
- specifier: ^3.0.12
- version: 3.0.12
+ specifier: ^3.0.13
+ version: 3.0.13
async-retry:
specifier: ^1.3.3
version: 1.3.3
@@ -225,8 +225,8 @@ dependencies:
specifier: ^10.16.4
version: 10.16.4(react-dom@18.2.0)(react@18.2.0)
helmet:
- specifier: ^7.0.0
- version: 7.0.0
+ specifier: ^7.1.0
+ version: 7.1.0
immer:
specifier: ^10.0.3
version: 10.0.3
@@ -264,8 +264,8 @@ dependencies:
specifier: ^6.9.7
version: 6.9.7
openai:
- specifier: ^4.16.0
- version: 4.16.0
+ specifier: ^4.16.1
+ version: 4.16.1
otplib:
specifier: ^12.0.1
version: 12.0.1
@@ -455,35 +455,35 @@ devDependencies:
specifier: 14.0.0
version: 14.0.0(react-dom@18.2.0)(react@18.2.0)
'@types/async-retry':
- specifier: ^1.4.7
- version: 1.4.7
+ specifier: ^1.4.8
+ version: 1.4.8
'@types/bcryptjs':
- specifier: ^2.4.5
- version: 2.4.5
+ specifier: ^2.4.6
+ version: 2.4.6
'@types/cookie-parser':
- specifier: ^1.4.5
- version: 1.4.5
+ specifier: ^1.4.6
+ version: 1.4.6
'@types/express':
- specifier: ^4.17.20
- version: 4.17.20
+ specifier: ^4.17.21
+ version: 4.17.21
'@types/file-saver':
- specifier: ^2.0.6
- version: 2.0.6
+ specifier: ^2.0.7
+ version: 2.0.7
'@types/jest':
specifier: ^29.5.7
version: 29.5.7
'@types/lodash.debounce':
- specifier: ^4.0.8
- version: 4.0.8
+ specifier: ^4.0.9
+ version: 4.0.9
'@types/lodash.get':
- specifier: ^4.4.8
- version: 4.4.8
+ specifier: ^4.4.9
+ version: 4.4.9
'@types/lodash.set':
- specifier: ^4.3.8
- version: 4.3.8
+ specifier: ^4.3.9
+ version: 4.3.9
'@types/multer':
- specifier: ^1.4.9
- version: 1.4.9
+ specifier: ^1.4.10
+ version: 1.4.10
'@types/node':
specifier: 20.8.10
version: 20.8.10
@@ -491,20 +491,20 @@ devDependencies:
specifier: ^6.4.13
version: 6.4.13
'@types/papaparse':
- specifier: ^5.3.10
- version: 5.3.10
+ specifier: ^5.3.11
+ version: 5.3.11
'@types/passport':
- specifier: ^1.0.14
- version: 1.0.14
+ specifier: ^1.0.15
+ version: 1.0.15
'@types/passport-github2':
- specifier: ^1.2.8
- version: 1.2.8
+ specifier: ^1.2.9
+ version: 1.2.9
'@types/passport-google-oauth20':
- specifier: ^2.0.13
- version: 2.0.13
+ specifier: ^2.0.14
+ version: 2.0.14
'@types/passport-local':
- specifier: ^1.0.37
- version: 1.0.37
+ specifier: ^1.0.38
+ version: 1.0.38
'@types/react':
specifier: 18.2.36
version: 18.2.36
@@ -2303,8 +2303,8 @@ packages:
- supports-color
dev: true
- /@dnd-kit/accessibility@3.0.1(react@18.2.0):
- resolution: {integrity: sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==}
+ /@dnd-kit/accessibility@3.1.0(react@18.2.0):
+ resolution: {integrity: sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==}
peerDependencies:
react: '>=16.8.0'
dependencies:
@@ -2312,45 +2312,45 @@ packages:
tslib: 2.6.2
dev: false
- /@dnd-kit/core@6.0.8(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==}
+ /@dnd-kit/core@6.1.0(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
dependencies:
- '@dnd-kit/accessibility': 3.0.1(react@18.2.0)
- '@dnd-kit/utilities': 3.2.1(react@18.2.0)
+ '@dnd-kit/accessibility': 3.1.0(react@18.2.0)
+ '@dnd-kit/utilities': 3.2.2(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
tslib: 2.6.2
dev: false
- /@dnd-kit/modifiers@6.0.1(@dnd-kit/core@6.0.8)(react@18.2.0):
- resolution: {integrity: sha512-rbxcsg3HhzlcMHVHWDuh9LCjpOVAgqbV78wLGI8tziXY3+qcMQ61qVXIvNKQFuhj75dSfD+o+PYZQ/NUk2A23A==}
+ /@dnd-kit/modifiers@7.0.0(@dnd-kit/core@6.1.0)(react@18.2.0):
+ resolution: {integrity: sha512-BG/ETy3eBjFap7+zIti53f0PCLGDzNXyTmn6fSdrudORf+OH04MxrW4p5+mPu4mgMk9kM41iYONjc3DOUWTcfg==}
peerDependencies:
- '@dnd-kit/core': ^6.0.6
+ '@dnd-kit/core': ^6.1.0
react: '>=16.8.0'
dependencies:
- '@dnd-kit/core': 6.0.8(react-dom@18.2.0)(react@18.2.0)
- '@dnd-kit/utilities': 3.2.1(react@18.2.0)
+ '@dnd-kit/core': 6.1.0(react-dom@18.2.0)(react@18.2.0)
+ '@dnd-kit/utilities': 3.2.2(react@18.2.0)
react: 18.2.0
tslib: 2.6.2
dev: false
- /@dnd-kit/sortable@7.0.2(@dnd-kit/core@6.0.8)(react@18.2.0):
- resolution: {integrity: sha512-wDkBHHf9iCi1veM834Gbk1429bd4lHX4RpAwT0y2cHLf246GAvU2sVw/oxWNpPKQNQRQaeGXhAVgrOl1IT+iyA==}
+ /@dnd-kit/sortable@8.0.0(@dnd-kit/core@6.1.0)(react@18.2.0):
+ resolution: {integrity: sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==}
peerDependencies:
- '@dnd-kit/core': ^6.0.7
+ '@dnd-kit/core': ^6.1.0
react: '>=16.8.0'
dependencies:
- '@dnd-kit/core': 6.0.8(react-dom@18.2.0)(react@18.2.0)
- '@dnd-kit/utilities': 3.2.1(react@18.2.0)
+ '@dnd-kit/core': 6.1.0(react-dom@18.2.0)(react@18.2.0)
+ '@dnd-kit/utilities': 3.2.2(react@18.2.0)
react: 18.2.0
tslib: 2.6.2
dev: false
- /@dnd-kit/utilities@3.2.1(react@18.2.0):
- resolution: {integrity: sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==}
+ /@dnd-kit/utilities@3.2.2(react@18.2.0):
+ resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==}
peerDependencies:
react: '>=16.8.0'
dependencies:
@@ -6769,8 +6769,8 @@ packages:
resolution: {integrity: sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA==}
dev: true
- /@types/async-retry@1.4.7:
- resolution: {integrity: sha512-4NH5wuf9x7LZWD23/knI6RBywD1qCmLm7wNaqq0riy7hdDrCGGfkPOUvx0Cb78lVrFrEnCvocoL8+UcvSQlBDw==}
+ /@types/async-retry@1.4.8:
+ resolution: {integrity: sha512-Qup/B5PWLe86yI5I3av6ePGaeQrIHNKCwbsQotD6aHQ6YkHsMUxVZkZsmx/Ry3VZQ6uysHwTjQ7666+k6UjVJA==}
dependencies:
'@types/retry': 0.12.4
dev: true
@@ -6804,8 +6804,8 @@ packages:
'@babel/types': 7.23.0
dev: true
- /@types/bcryptjs@2.4.5:
- resolution: {integrity: sha512-tOF6TivOIvq+TWQm78335CMdyVJhpBG3NUdWQDAp95ax4E2rSKbws/ELHLk5EBoucwx/tHt3/hhLOHwWJgVrSw==}
+ /@types/bcryptjs@2.4.6:
+ resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==}
dev: true
/@types/body-parser@1.19.4:
@@ -6851,10 +6851,10 @@ packages:
dependencies:
'@types/node': 20.8.10
- /@types/cookie-parser@1.4.5:
- resolution: {integrity: sha512-cbpH1NldYslPt7WRHXZFm+G7DTfUg57dQSCf1qrHwT8wtGX41JHLYf3Cieiqg7waPWjorVgcSSllZov+A1PJbg==}
+ /@types/cookie-parser@1.4.6:
+ resolution: {integrity: sha512-KoooCrD56qlLskXPLGUiJxOMnv5l/8m7cQD2OxJ73NPMhuSz9PmvwRD6EpjDyKBVrdJDdQ4bQK7JFNHnNmax0w==}
dependencies:
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
dev: true
/@types/ejs@3.1.4:
@@ -6888,16 +6888,16 @@ packages:
'@types/range-parser': 1.2.6
'@types/send': 0.17.3
- /@types/express@4.17.20:
- resolution: {integrity: sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==}
+ /@types/express@4.17.21:
+ resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
dependencies:
'@types/body-parser': 1.19.4
'@types/express-serve-static-core': 4.17.39
'@types/qs': 6.9.9
'@types/serve-static': 1.15.4
- /@types/file-saver@2.0.6:
- resolution: {integrity: sha512-Mw671DVqoMHbjw0w4v2iiOro01dlT/WhWp5uwecBa0Wg8c+bcZOjgF1ndBnlaxhtvFCgTRBtsGivSVhrK/vnag==}
+ /@types/file-saver@2.0.7:
+ resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==}
dev: true
/@types/graceful-fs@4.1.8:
@@ -6975,20 +6975,20 @@ packages:
'@types/node': 20.8.10
dev: true
- /@types/lodash.debounce@4.0.8:
- resolution: {integrity: sha512-REumepIJjQFSOaBUoj81U5ZzF9YIhovzE2Lm6ejUbycmwx597k2ivG1cVfPtAj4eVuSbGoZDkJR0sRIahsE6/Q==}
+ /@types/lodash.debounce@4.0.9:
+ resolution: {integrity: sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==}
dependencies:
'@types/lodash': 4.14.200
dev: true
- /@types/lodash.get@4.4.8:
- resolution: {integrity: sha512-XK+co6sBkJxh1vaVP8al6cAA17dX//RNCknGG8JhpHFJfxq/GXKAYB9NKheG22pu2xpWpxfFd65W08EhH2IFlg==}
+ /@types/lodash.get@4.4.9:
+ resolution: {integrity: sha512-J5dvW98sxmGnamqf+/aLP87PYXyrha9xIgc2ZlHl6OHMFR2Ejdxep50QfU0abO1+CH6+ugx+8wEUN1toImAinA==}
dependencies:
'@types/lodash': 4.14.200
dev: true
- /@types/lodash.set@4.3.8:
- resolution: {integrity: sha512-WYIWnVO5xkcEKehhZf0Whrf9wj9D1AuaGTpwT/mCEJXKgdC2UWcMpvRqJahKQNhnOjmGEhpUqbYNJ6gUgdGSQw==}
+ /@types/lodash.set@4.3.9:
+ resolution: {integrity: sha512-KOxyNkZpbaggVmqbpr82N2tDVTx05/3/j0f50Es1prxrWB0XYf9p3QNxqcbWb7P1Q9wlvsUSlCFnwlPCIJ46PQ==}
dependencies:
'@types/lodash': 4.14.200
dev: true
@@ -7007,10 +7007,10 @@ packages:
resolution: {integrity: sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==}
dev: true
- /@types/multer@1.4.9:
- resolution: {integrity: sha512-9NSvPJ2E8bNTc8XtJq1Cimx2Wrn2Ah48F15B2Du/hM8a8CHLhVbJMlF3ZCqhvMdht7Sa+YdP0aKP7N4fxDcrrg==}
+ /@types/multer@1.4.10:
+ resolution: {integrity: sha512-6l9mYMhUe8wbnz/67YIjc7ZJyQNZoKq7fRXVf7nMdgWgalD0KyzJ2ywI7hoATUSXSbTu9q2HBiEwzy0tNN1v2w==}
dependencies:
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
dev: true
/@types/node-fetch@2.6.8:
@@ -7060,8 +7060,8 @@ packages:
resolution: {integrity: sha512-qZqHmdGEALeSATMB1djT1S5szv6Wtpb7DKpHrt2XG4iyKlV7C2Xk8GmDXr1KXakOqUfX6ohw7ceruYt4NVmB1Q==}
dev: false
- /@types/papaparse@5.3.10:
- resolution: {integrity: sha512-mS1Fta/xJ9EDYmAvpeWzcV9Gr0cOl1ClpW7di9+wSUNDIDO55tBtyXg97O7K+Syrd9rDEmuejM2iqmJIJ1SO5g==}
+ /@types/papaparse@5.3.11:
+ resolution: {integrity: sha512-ISil0lMkpRDrBTKRPnUgVb5IqxWwj19gWBrX/ROk3pbkkslBN3URa713r/BSfAUj+w9gTPg3S3f45aMToVfh1w==}
dependencies:
'@types/node': 20.8.10
dev: true
@@ -7070,56 +7070,56 @@ packages:
resolution: {integrity: sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng==}
dev: true
- /@types/passport-github2@1.2.8:
- resolution: {integrity: sha512-OD1WQ5AOIyTHgBWYJxG/yudHhojAfZXLpidzyoohjwFfu5sjJf/A5J23sm8YCQpnDjcWwaPFQ/NB7XC3QZjNJg==}
+ /@types/passport-github2@1.2.9:
+ resolution: {integrity: sha512-/nMfiPK2E6GKttwBzwj0Wjaot8eHrM57hnWxu52o6becr5/kXlH/4yE2v2rh234WGvSgEEzIII02Nc5oC5xEHA==}
dependencies:
- '@types/express': 4.17.20
- '@types/passport': 1.0.14
+ '@types/express': 4.17.21
+ '@types/passport': 1.0.15
'@types/passport-oauth2': 1.4.14
dev: true
- /@types/passport-google-oauth20@2.0.13:
- resolution: {integrity: sha512-idIhUp1RyBqk8cgApCHvqIvk09QVZv83hQJ/39VonIHYZkBps8p0AfB9INtPee3iuittdFx9J+i35pdZBgCqUQ==}
+ /@types/passport-google-oauth20@2.0.14:
+ resolution: {integrity: sha512-ZaZpRUAeMl3vy298ulKO1wGLn9SQtj/CyIfZL/Px5xU9pybMiQU3mhXDCBiWSbg0EK9uXT4ZoWC3ktuWY+5fwQ==}
dependencies:
- '@types/express': 4.17.20
- '@types/passport': 1.0.14
+ '@types/express': 4.17.21
+ '@types/passport': 1.0.15
'@types/passport-oauth2': 1.4.14
dev: true
- /@types/passport-jwt@3.0.12:
- resolution: {integrity: sha512-nXCd1lu20rw//nZ5AnK1FnlVZdSC4R5xksquev9oAJlXwJw0irMdZ7dRAE4KDlalptKObiaoam6BQ8lpujeZog==}
+ /@types/passport-jwt@3.0.13:
+ resolution: {integrity: sha512-fjHaC6Bv8EpMMqzTnHP32SXlZGaNfBPC/Po5dmRGYi2Ky7ljXPbGnOy+SxZqa6iZvFgVhoJ1915Re3m93zmcfA==}
dependencies:
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
'@types/jsonwebtoken': 9.0.4
'@types/passport-strategy': 0.2.37
dev: false
- /@types/passport-local@1.0.37:
- resolution: {integrity: sha512-c57CwMHhMP2BBiOLyQZGRP43F8JtC84H976YVJdiU4EIWvqRCZ3F7QtsEgksOEIgMOk1Kz3EEKGA93OiDPQtRQ==}
+ /@types/passport-local@1.0.38:
+ resolution: {integrity: sha512-nsrW4A963lYE7lNTv9cr5WmiUD1ibYJvWrpE13oxApFsRt77b0RdtZvKbCdNIY4v/QZ6TRQWaDDEwV1kCTmcXg==}
dependencies:
- '@types/express': 4.17.20
- '@types/passport': 1.0.14
+ '@types/express': 4.17.21
+ '@types/passport': 1.0.15
'@types/passport-strategy': 0.2.37
dev: true
/@types/passport-oauth2@1.4.14:
resolution: {integrity: sha512-wZBvnRwqdvm35l1Jn9ebYm2Q7UtxYIdBu1PjoKXMoxJytniVjXxYJmrlDXn5fMZROWbJbnEnp1XSDANqtvMdGQ==}
dependencies:
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
'@types/oauth': 0.9.3
- '@types/passport': 1.0.14
+ '@types/passport': 1.0.15
dev: true
/@types/passport-strategy@0.2.37:
resolution: {integrity: sha512-ltgwLnwHVfpjK7/66lpv43hiz90nIVb36JmeB0iF3FAZoHX6+LbkY5Ey97Bm8Jr0uGhQyDFEsSOOfejp5PJehg==}
dependencies:
- '@types/express': 4.17.20
- '@types/passport': 1.0.14
+ '@types/express': 4.17.21
+ '@types/passport': 1.0.15
- /@types/passport@1.0.14:
- resolution: {integrity: sha512-D6p2ygR2S7Cq5PO7iUaEIQu/5WrM0tONu6Lxgk0C9r3lafQIlVpWCo3V/KI9To3OqHBxcfQaOeK+8AvwW5RYmw==}
+ /@types/passport@1.0.15:
+ resolution: {integrity: sha512-oHOgzPBp5eLI1U/7421qYV/ZySQXMYCBSfRkDe1tQ0YrIbLY/M/76qIXE7Bs7lFyvw1x5QqiNQ9imvh0fQHe9Q==}
dependencies:
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
/@types/prop-types@15.7.9:
resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==}
@@ -7183,7 +7183,7 @@ packages:
/@types/serve-index@1.9.3:
resolution: {integrity: sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg==}
dependencies:
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
dev: true
/@types/serve-static@1.15.4:
@@ -12073,8 +12073,8 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
- /helmet@7.0.0:
- resolution: {integrity: sha512-MsIgYmdBh460ZZ8cJC81q4XJknjG567wzEmv46WOBblDb6TUd3z8/GhgmsM9pn8g2B80tAJ4m5/d3Bi1KrSUBQ==}
+ /helmet@7.1.0:
+ resolution: {integrity: sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==}
engines: {node: '>=16.0.0'}
dev: false
@@ -12253,7 +12253,7 @@ packages:
- supports-color
dev: false
- /http-proxy-middleware@2.0.6(@types/express@4.17.20):
+ /http-proxy-middleware@2.0.6(@types/express@4.17.21):
resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==}
engines: {node: '>=12.0.0'}
peerDependencies:
@@ -12262,7 +12262,7 @@ packages:
'@types/express':
optional: true
dependencies:
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
'@types/http-proxy': 1.17.13
http-proxy: 1.18.1
is-glob: 4.0.3
@@ -15397,8 +15397,8 @@ packages:
is-wsl: 2.2.0
dev: true
- /openai@4.16.0:
- resolution: {integrity: sha512-P7IWqvaP0EuD3cQvzmU24KprnS0tHavrTuMiChEOa7pugqrKUfcmTnHcr+w01sJHny3vYoTvydCZ77cQolYj+g==}
+ /openai@4.16.1:
+ resolution: {integrity: sha512-Gr+uqUN1ICSk6VhrX64E+zL7skjI1TgPr/XUN+ZQuNLLOvx15+XZulx/lSW4wFEAQzgjBDlMBbBeikguGIjiMg==}
hasBin: true
dependencies:
'@types/node': 18.18.8
@@ -19675,7 +19675,7 @@ packages:
dependencies:
'@types/bonjour': 3.5.12
'@types/connect-history-api-fallback': 1.5.2
- '@types/express': 4.17.20
+ '@types/express': 4.17.21
'@types/serve-index': 1.9.3
'@types/serve-static': 1.15.4
'@types/sockjs': 0.3.35
@@ -19690,7 +19690,7 @@ packages:
express: 4.18.2
graceful-fs: 4.2.11
html-entities: 2.4.0
- http-proxy-middleware: 2.0.6(@types/express@4.17.20)
+ http-proxy-middleware: 2.0.6(@types/express@4.17.21)
ipaddr.js: 2.1.0
launch-editor: 2.6.1
open: 8.4.2
diff --git a/tsconfig.base.json b/tsconfig.base.json
index b36e5a245..c73496a23 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -15,15 +15,13 @@
"skipDefaultLibCheck": true,
"baseUrl": ".",
"paths": {
- // App Paths
"@/client/*": ["apps/client/src/*"],
"@/server/*": ["apps/server/src/*"],
- // Library Paths
+ "@/artboard/*": ["apps/artboard/src/*"],
"@reactive-resume/dto": ["libs/dto/src/index.ts"],
"@reactive-resume/hooks": ["libs/hooks/src/index.ts"],
"@reactive-resume/parser": ["libs/parser/src/index.ts"],
"@reactive-resume/schema": ["libs/schema/src/index.ts"],
- "@reactive-resume/templates": ["libs/templates/src/index.ts"],
"@reactive-resume/ui": ["libs/ui/src/index.ts"],
"@reactive-resume/utils": ["libs/utils/src/index.ts"]
}