From c9a2c27b2d1a5a8e0870bc65a8a61fe4e720f22a Mon Sep 17 00:00:00 2001 From: Shubham Mathur Date: Thu, 27 Jun 2024 14:59:13 +0530 Subject: [PATCH 01/34] fix(edit profile picture): fix the crash happening when clicking on circular border radius --- .../pages/builder/sidebars/left/sections/picture/options.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/client/src/pages/builder/sidebars/left/sections/picture/options.tsx b/apps/client/src/pages/builder/sidebars/left/sections/picture/options.tsx index c561911c..356f00cf 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/picture/options.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/picture/options.tsx @@ -61,8 +61,9 @@ export const PictureOptions = () => { return borderRadiusToStringMap[radius]; }, [picture.borderRadius]); - const onBorderRadiusChange = (value: BorderRadius) => { - setValue("basics.picture.borderRadius", stringToBorderRadiusMap[value]); + const onBorderRadiusChange = (value: string) => { + if (!value) return; + setValue("basics.picture.borderRadius", stringToBorderRadiusMap[value as BorderRadius]); }; return ( From 304fd93eceae1a0d0c16891039b6ba5705b219cd Mon Sep 17 00:00:00 2001 From: Scott Busche Date: Sun, 4 Aug 2024 14:20:41 -0500 Subject: [PATCH 02/34] Update CONTRIBUTING.md for Node 20 package.json and GitHub Actions both run with Node 20 --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0fbc9a09..3501deab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ To run the development environment of the application locally on your computer, #### Requirements - Docker (with Docker Compose) -- Node.js 18 or higher (with pnpm) +- Node.js 20 or higher (with pnpm) ### 1. Fork and Clone the Repository From acc9becf1a06d4192f6cd2b8e1021f0e86d021e8 Mon Sep 17 00:00:00 2001 From: infinia-yzl Date: Wed, 14 Aug 2024 15:41:54 +0800 Subject: [PATCH 03/34] feat(toggle-pan): Add toggle to switch between scroll to pan and scroll to zoom - Modify wheel behaviour to pan by default for a more natural behaviour with trackpads (https://github.com/BetterTyped/react-zoom-pan-pinch/pull/447) - Bump `react-zoom-pan-pinch` version to `3.6.1` from `3.4.4` --- apps/artboard/src/pages/builder.tsx | 13 ++++++++++- .../src/pages/builder/_components/toolbar.tsx | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/apps/artboard/src/pages/builder.tsx b/apps/artboard/src/pages/builder.tsx index f339eca3..9272d6ea 100644 --- a/apps/artboard/src/pages/builder.tsx +++ b/apps/artboard/src/pages/builder.tsx @@ -1,7 +1,7 @@ import { SectionKey } from "@reactive-resume/schema"; import { pageSizeMap, Template } from "@reactive-resume/utils"; import { AnimatePresence, motion } from "framer-motion"; -import { useEffect, useMemo, useRef } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { ReactZoomPanPinchRef, TransformComponent, TransformWrapper } from "react-zoom-pan-pinch"; import { MM_TO_PX, Page } from "../components/page"; @@ -14,6 +14,8 @@ export const BuilderLayout = () => { const layout = useArtboardStore((state) => state.resume.metadata.layout); const template = useArtboardStore((state) => state.resume.metadata.template as Template); + const [wheelPanning, setWheelPanning] = useState(true); + const Template = useMemo(() => getTemplate(template), [template]); useEffect(() => { @@ -27,6 +29,9 @@ export const BuilderLayout = () => { transformRef.current?.resetTransform(0); setTimeout(() => transformRef.current?.centerView(0.8, 0), 10); } + if (event.data.type === "TOGGLE_PAN_MODE") { + setWheelPanning(event.data.panMode); + } }; window.addEventListener("message", handleMessage); @@ -44,6 +49,12 @@ export const BuilderLayout = () => { minScale={0.4} initialScale={0.8} limitToBounds={false} + panning={{ + wheelPanning: wheelPanning, + }} + wheel={{ + wheelDisabled: wheelPanning, + }} > { const win = window.open(url, "_blank"); @@ -31,6 +34,7 @@ export const BuilderToolbar = () => { const undo = useTemporalResumeStore((state) => state.undo); const redo = useTemporalResumeStore((state) => state.redo); const frameRef = useBuilderStore((state) => state.frame.ref); + const [panMode, setPanMode] = useState(true); const id = useResumeStore((state) => state.resume.id); const isPublic = useResumeStore((state) => state.resume.visibility === "public"); @@ -59,6 +63,10 @@ export const BuilderToolbar = () => { const onZoomOut = () => frameRef?.contentWindow?.postMessage({ type: "ZOOM_OUT" }, "*"); const onResetView = () => frameRef?.contentWindow?.postMessage({ type: "RESET_VIEW" }, "*"); const onCenterView = () => frameRef?.contentWindow?.postMessage({ type: "CENTER_VIEW" }, "*"); + const onTogglePanMode = () => { + setPanMode(!panMode); // local button state + frameRef?.contentWindow?.postMessage({ type: "TOGGLE_PAN_MODE", panMode: !panMode }, "*"); // toggle artboard state + }; return ( @@ -91,6 +99,20 @@ export const BuilderToolbar = () => { + + + {panMode ? : } + + + + + {isEnabled && ( diff --git a/apps/client/src/services/openai/change-tone.ts b/apps/client/src/services/openai/change-tone.ts index a6182197..4ac3d814 100644 --- a/apps/client/src/services/openai/change-tone.ts +++ b/apps/client/src/services/openai/change-tone.ts @@ -3,6 +3,8 @@ import { t } from "@lingui/macro"; import { openai } from "./client"; +import { useOpenAiStore } from "@/client/stores/openai"; +import { DEFAULT_MAX_TOKENS, DEFAULT_MODEL } from "@/client/constants/llm"; const PROMPT = `You are an AI writing assistant specialized in writing copy for resumes. Do not return anything else except the text you improved. It should not begin with a newline. It should not have any prefix or suffix text. @@ -17,10 +19,12 @@ type Mood = "casual" | "professional" | "confident" | "friendly"; export const changeTone = async (text: string, mood: Mood) => { const prompt = PROMPT.replace("{mood}", mood).replace("{input}", text); + const { model, maxTokens } = useOpenAiStore.getState(); + const result = await openai().chat.completions.create({ messages: [{ role: "user", content: prompt }], - model: "gpt-3.5-turbo", - max_tokens: 1024, + model: model ?? DEFAULT_MODEL, + max_tokens: maxTokens ?? DEFAULT_MAX_TOKENS, temperature: 0.5, stop: ['"""'], n: 1, diff --git a/apps/client/src/services/openai/client.ts b/apps/client/src/services/openai/client.ts index 9d000bd5..42a915e6 100644 --- a/apps/client/src/services/openai/client.ts +++ b/apps/client/src/services/openai/client.ts @@ -4,7 +4,7 @@ import { OpenAI } from "openai"; import { useOpenAiStore } from "@/client/stores/openai"; export const openai = () => { - const { apiKey } = useOpenAiStore.getState(); + const { apiKey, baseURL } = useOpenAiStore.getState(); if (!apiKey) { throw new Error( @@ -12,6 +12,14 @@ export const openai = () => { ); } + if(baseURL) { + return new OpenAI({ + baseURL, + apiKey, + dangerouslyAllowBrowser: true, + }); + } + return new OpenAI({ apiKey, dangerouslyAllowBrowser: true, diff --git a/apps/client/src/services/openai/fix-grammar.ts b/apps/client/src/services/openai/fix-grammar.ts index 2c8b0e3e..b3a85307 100644 --- a/apps/client/src/services/openai/fix-grammar.ts +++ b/apps/client/src/services/openai/fix-grammar.ts @@ -3,6 +3,8 @@ import { t } from "@lingui/macro"; import { openai } from "./client"; +import { useOpenAiStore } from "@/client/stores/openai"; +import { DEFAULT_MAX_TOKENS, DEFAULT_MODEL } from "@/client/constants/llm"; const PROMPT = `You are an AI writing assistant specialized in writing copy for resumes. Do not return anything else except the text you improved. It should not begin with a newline. It should not have any prefix or suffix text. @@ -15,10 +17,12 @@ Revised Text: """`; export const fixGrammar = async (text: string) => { const prompt = PROMPT.replace("{input}", text); + const { model, maxTokens } = useOpenAiStore.getState(); + const result = await openai().chat.completions.create({ messages: [{ role: "user", content: prompt }], - model: "gpt-3.5-turbo", - max_tokens: 1024, + model: model ?? DEFAULT_MODEL, + max_tokens: maxTokens ?? DEFAULT_MAX_TOKENS, temperature: 0, stop: ['"""'], n: 1, diff --git a/apps/client/src/services/openai/improve-writing.ts b/apps/client/src/services/openai/improve-writing.ts index 4132b5ae..ff1419af 100644 --- a/apps/client/src/services/openai/improve-writing.ts +++ b/apps/client/src/services/openai/improve-writing.ts @@ -3,6 +3,8 @@ import { t } from "@lingui/macro"; import { openai } from "./client"; +import { useOpenAiStore } from "@/client/stores/openai"; +import { DEFAULT_MAX_TOKENS, DEFAULT_MODEL } from "@/client/constants/llm"; const PROMPT = `You are an AI writing assistant specialized in writing copy for resumes. Do not return anything else except the text you improved. It should not begin with a newline. It should not have any prefix or suffix text. @@ -15,10 +17,12 @@ Revised Text: """`; export const improveWriting = async (text: string) => { const prompt = PROMPT.replace("{input}", text); + const { model, maxTokens } = useOpenAiStore.getState(); + const result = await openai().chat.completions.create({ messages: [{ role: "user", content: prompt }], - model: "gpt-3.5-turbo", - max_tokens: 1024, + model: model ?? DEFAULT_MODEL, + max_tokens: maxTokens ?? DEFAULT_MAX_TOKENS, temperature: 0, stop: ['"""'], n: 1, diff --git a/apps/client/src/stores/openai.ts b/apps/client/src/stores/openai.ts index 9b9d1ea6..8d279d90 100644 --- a/apps/client/src/stores/openai.ts +++ b/apps/client/src/stores/openai.ts @@ -1,18 +1,37 @@ import { create } from "zustand"; import { persist } from "zustand/middleware"; +import { DEFAULT_MAX_TOKENS, DEFAULT_MODEL } from "../constants/llm"; type OpenAIStore = { + baseURL: string | null; + setBaseURL: (baseURL: string | null) => void; apiKey: string | null; setApiKey: (apiKey: string | null) => void; + model: string | null; + setModel: (model: string | null) => void; + maxTokens: number | null; + setMaxTokens: (maxTokens: number | null) => void; }; export const useOpenAiStore = create()( persist( (set) => ({ + baseURL: null, + setBaseURL: (baseURL: string | null) => { + set({ baseURL }); + }, apiKey: null, - setApiKey: (apiKey) => { + setApiKey: (apiKey: string | null) => { set({ apiKey }); }, + model: DEFAULT_MODEL, + setModel: (model: string | null) => { + set({ model }); + }, + maxTokens: DEFAULT_MAX_TOKENS, + setMaxTokens: (maxTokens: number | null) => { + set({ maxTokens }); + }, }), { name: "openai" }, ), From 700b98fcb79f9451108e69852859a08a6765d90a Mon Sep 17 00:00:00 2001 From: raymondyangdev Date: Tue, 5 Nov 2024 17:35:14 +1300 Subject: [PATCH 11/34] fix(templates): Add right border in header after website field with custom fields in Rhyhorn --- apps/artboard/src/templates/rhyhorn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/artboard/src/templates/rhyhorn.tsx b/apps/artboard/src/templates/rhyhorn.tsx index 5c41a4c7..d1c06f05 100644 --- a/apps/artboard/src/templates/rhyhorn.tsx +++ b/apps/artboard/src/templates/rhyhorn.tsx @@ -124,7 +124,7 @@ const Link = ({ url, icon, iconOnRight, label, className }: LinkProps) => { if (!isUrl(url.href)) return null; return ( -
+
{!iconOnRight && (icon ?? )} Date: Thu, 7 Nov 2024 10:16:35 -0800 Subject: [PATCH 12/34] fix: refine "localhost" matching in printer.service.ts changed localhost matching for local dev environments from a url string match to more specific regex that matches host property. This was causing the "about:blank", no output error in (edge) case of printing a pdf from any url with string "localhost" --- apps/server/src/printer/printer.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/server/src/printer/printer.service.ts b/apps/server/src/printer/printer.service.ts index e26667ee..f3f084d5 100644 --- a/apps/server/src/printer/printer.service.ts +++ b/apps/server/src/printer/printer.service.ts @@ -101,17 +101,17 @@ export class PrinterService { let url = publicUrl; - if ([publicUrl, storageUrl].some((url) => url.includes("localhost"))) { - // Switch client URL from `localhost` to `host.docker.internal` in development + if ([publicUrl, storageUrl].some((url) => /https?:\/\/localhost(:\d+)?/.test(url))) { + // Switch client URL from `http[s]://localhost[:port]` to `http[s]://host.docker.internal[:port]` in development // This is required because the browser is running in a container and the client is running on the host machine. - url = url.replace("localhost", "host.docker.internal"); - + url = url.replace(/localhost(:\d+)?/, "host.docker.internal"); + await page.setRequestInterception(true); // Intercept requests of `localhost` to `host.docker.internal` in development page.on("request", (request) => { if (request.url().startsWith(storageUrl)) { - const modifiedUrl = request.url().replace("localhost", `host.docker.internal`); + const modifiedUrl = request.url().replace(/localhost(:\d+)?/, "host.docker.internal"); void request.continue({ url: modifiedUrl }); } else { From c87242142d1139e591065739f6656f12a88800e1 Mon Sep 17 00:00:00 2001 From: 0x346e3730 Date: Thu, 14 Nov 2024 09:39:57 +0400 Subject: [PATCH 13/34] feat(templates): make main full-width if sidebar is empty --- apps/artboard/src/templates/azurill.tsx | 2 +- apps/artboard/src/templates/chikorita.tsx | 4 ++-- apps/artboard/src/templates/ditto.tsx | 2 +- apps/artboard/src/templates/gengar.tsx | 2 +- apps/artboard/src/templates/glalie.tsx | 4 ++-- apps/artboard/src/templates/leafish.tsx | 4 ++-- apps/artboard/src/templates/pikachu.tsx | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/artboard/src/templates/azurill.tsx b/apps/artboard/src/templates/azurill.tsx index 0ead0536..5d88f15d 100644 --- a/apps/artboard/src/templates/azurill.tsx +++ b/apps/artboard/src/templates/azurill.tsx @@ -574,7 +574,7 @@ export const Azurill = ({ columns, isFirstPage = false }: TemplateProps) => { ))}
-
+
{main.map((section) => ( {mapSectionToComponent(section)} ))} diff --git a/apps/artboard/src/templates/chikorita.tsx b/apps/artboard/src/templates/chikorita.tsx index cd30b0e4..d60962ca 100644 --- a/apps/artboard/src/templates/chikorita.tsx +++ b/apps/artboard/src/templates/chikorita.tsx @@ -578,7 +578,7 @@ export const Chikorita = ({ columns, isFirstPage = false }: TemplateProps) => { return (
-
+
{isFirstPage &&
} {main.map((section) => ( @@ -586,7 +586,7 @@ export const Chikorita = ({ columns, isFirstPage = false }: TemplateProps) => { ))}
-
+
{sidebar.map((section) => ( {mapSectionToComponent(section)} ))} diff --git a/apps/artboard/src/templates/ditto.tsx b/apps/artboard/src/templates/ditto.tsx index c0b81da4..442d9a87 100644 --- a/apps/artboard/src/templates/ditto.tsx +++ b/apps/artboard/src/templates/ditto.tsx @@ -621,7 +621,7 @@ export const Ditto = ({ columns, isFirstPage = false }: TemplateProps) => { ))}
-
+
{main.map((section) => ( {mapSectionToComponent(section)} ))} diff --git a/apps/artboard/src/templates/gengar.tsx b/apps/artboard/src/templates/gengar.tsx index 44d5eb57..35c1b6bd 100644 --- a/apps/artboard/src/templates/gengar.tsx +++ b/apps/artboard/src/templates/gengar.tsx @@ -599,7 +599,7 @@ export const Gengar = ({ columns, isFirstPage = false }: TemplateProps) => {
-
+
{isFirstPage && (
{ return (
{isFirstPage &&
} @@ -601,7 +601,7 @@ export const Glalie = ({ columns, isFirstPage = false }: TemplateProps) => { ))}
-
+
{main.map((section) => ( {mapSectionToComponent(section)} ))} diff --git a/apps/artboard/src/templates/leafish.tsx b/apps/artboard/src/templates/leafish.tsx index c6b12f97..c7347ff3 100644 --- a/apps/artboard/src/templates/leafish.tsx +++ b/apps/artboard/src/templates/leafish.tsx @@ -527,13 +527,13 @@ export const Leafish = ({ columns, isFirstPage = false }: TemplateProps) => { {isFirstPage &&
}
-
+
{main.map((section) => ( {mapSectionToComponent(section)} ))}
-
+
{sidebar.map((section) => ( {mapSectionToComponent(section)} ))} diff --git a/apps/artboard/src/templates/pikachu.tsx b/apps/artboard/src/templates/pikachu.tsx index 4cbe61c3..08b54091 100644 --- a/apps/artboard/src/templates/pikachu.tsx +++ b/apps/artboard/src/templates/pikachu.tsx @@ -621,7 +621,7 @@ export const Pikachu = ({ columns, isFirstPage = false }: TemplateProps) => { ))}
-
+
{isFirstPage &&
} {main.map((section) => ( From d84aeee968ed197ee3ff3dd852b397cf18b70f03 Mon Sep 17 00:00:00 2001 From: Karanrajsinh Date: Sat, 30 Nov 2024 19:32:04 +0530 Subject: [PATCH 14/34] fix(builderpage): resolve section-dialog height overflow for mobile and adjust sidebar font and spacing styles --- .../src/pages/builder/sidebars/left/index.tsx | 2 +- .../builder/sidebars/left/sections/basics.tsx | 4 +- .../left/sections/shared/section-base.tsx | 8 ++- .../left/sections/shared/section-dialog.tsx | 54 ++++++++++--------- .../left/sections/shared/section-options.tsx | 2 +- .../sidebars/left/sections/summary.tsx | 2 +- .../sidebars/right/sections/export.tsx | 2 +- .../sidebars/right/sections/information.tsx | 2 +- .../sidebars/right/sections/layout.tsx | 4 +- .../builder/sidebars/right/sections/notes.tsx | 2 +- .../builder/sidebars/right/sections/page.tsx | 4 +- .../sidebars/right/sections/sharing.tsx | 2 +- .../sidebars/right/sections/statistics.tsx | 2 +- .../sidebars/right/sections/template.tsx | 4 +- .../builder/sidebars/right/sections/theme.tsx | 4 +- .../sidebars/right/sections/typography.tsx | 8 +-- 16 files changed, 58 insertions(+), 48 deletions(-) diff --git a/apps/client/src/pages/builder/sidebars/left/index.tsx b/apps/client/src/pages/builder/sidebars/left/index.tsx index bdfe5b3b..f4d03474 100644 --- a/apps/client/src/pages/builder/sidebars/left/index.tsx +++ b/apps/client/src/pages/builder/sidebars/left/index.tsx @@ -161,7 +161,7 @@ export const LeftSidebar = () => {
-
+
diff --git a/apps/client/src/pages/builder/sidebars/left/sections/basics.tsx b/apps/client/src/pages/builder/sidebars/left/sections/basics.tsx index 20a2e099..fc45f8e5 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/basics.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/basics.tsx @@ -18,7 +18,7 @@ export const BasicsSection = () => {
{getSectionIcon("basics")} -

{t`Basics`}

+

{t`Basics`}

@@ -27,7 +27,7 @@ export const BasicsSection = () => {
-
+
({ id, title, description }: P
{getSectionIcon(id)} -

{section.name}

+

{section.name}

@@ -158,7 +158,11 @@ export const SectionBase = ({ id, title, description }: P {section.items.length > 0 && (
- - - + + + + + diff --git a/apps/client/src/pages/builder/sidebars/left/sections/shared/section-options.tsx b/apps/client/src/pages/builder/sidebars/left/sections/shared/section-options.tsx index 5766c452..922f50f6 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/shared/section-options.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/shared/section-options.tsx @@ -82,7 +82,7 @@ export const SectionOptions = ({ id }: Props) => { - + {hasItems && ( <> diff --git a/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx b/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx index de30bdad..fe5fb766 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx @@ -20,7 +20,7 @@ export const SummarySection = () => {
{getSectionIcon("summary")} -

{section.name}

+

{section.name}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/export.tsx b/apps/client/src/pages/builder/sidebars/right/sections/export.tsx index 9c95f1f6..f17df21e 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/export.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/export.tsx @@ -37,7 +37,7 @@ export const ExportSection = () => {
{getSectionIcon("export")} -

{t`Export`}

+

{t`Export`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/information.tsx b/apps/client/src/pages/builder/sidebars/right/sections/information.tsx index eb1b2498..b5c37165 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/information.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/information.tsx @@ -114,7 +114,7 @@ export const InformationSection = () => {
{getSectionIcon("information")} -

{t`Information`}

+

{t`Information`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx b/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx index b0e07bd8..7b14f509 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx @@ -204,7 +204,7 @@ export const LayoutSection = () => {
{getSectionIcon("layout")} -

{t`Layout`}

+

{t`Layout`}

@@ -268,7 +268,7 @@ export const LayoutSection = () => { diff --git a/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx b/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx index e63bef04..cc64da68 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx @@ -14,7 +14,7 @@ export const NotesSection = () => {
{getSectionIcon("notes")} -

{t`Notes`}

+

{t`Notes`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/page.tsx b/apps/client/src/pages/builder/sidebars/right/sections/page.tsx index 80c80662..4e262127 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/page.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/page.tsx @@ -23,11 +23,11 @@ export const PageSection = () => {
{getSectionIcon("page")} -

{t`Page`}

+

{t`Page`}

-
+
+ @@ -79,7 +79,7 @@ export const ProfilesDialog = () => { {t`Website`} - + @@ -100,7 +100,7 @@ export const ProfilesDialog = () => { { field.onChange(event); handleIconChange(event); diff --git a/apps/client/src/pages/builder/sidebars/left/dialogs/projects.tsx b/apps/client/src/pages/builder/sidebars/left/dialogs/projects.tsx index af1f7c2a..923aa226 100644 --- a/apps/client/src/pages/builder/sidebars/left/dialogs/projects.tsx +++ b/apps/client/src/pages/builder/sidebars/left/dialogs/projects.tsx @@ -111,7 +111,13 @@ export const ProjectsDialog = () => { {...field} content={field.value} footer={(editor) => ( - + { + editor.commands.setContent(value, true); + field.onChange(value); + }} + /> )} onChange={(value) => { field.onChange(value); diff --git a/apps/client/src/pages/builder/sidebars/left/dialogs/publications.tsx b/apps/client/src/pages/builder/sidebars/left/dialogs/publications.tsx index d42d7526..c1c1651a 100644 --- a/apps/client/src/pages/builder/sidebars/left/dialogs/publications.tsx +++ b/apps/client/src/pages/builder/sidebars/left/dialogs/publications.tsx @@ -98,7 +98,13 @@ export const PublicationsDialog = () => { {...field} content={field.value} footer={(editor) => ( - + { + editor.commands.setContent(value, true); + field.onChange(value); + }} + /> )} onChange={(value) => { field.onChange(value); diff --git a/apps/client/src/pages/builder/sidebars/left/dialogs/references.tsx b/apps/client/src/pages/builder/sidebars/left/dialogs/references.tsx index 71ad8ca6..617e58a9 100644 --- a/apps/client/src/pages/builder/sidebars/left/dialogs/references.tsx +++ b/apps/client/src/pages/builder/sidebars/left/dialogs/references.tsx @@ -84,7 +84,13 @@ export const ReferencesDialog = () => { {...field} content={field.value} footer={(editor) => ( - + { + editor.commands.setContent(value, true); + field.onChange(value); + }} + /> )} onChange={(value) => { field.onChange(value); diff --git a/apps/client/src/pages/builder/sidebars/left/dialogs/skills.tsx b/apps/client/src/pages/builder/sidebars/left/dialogs/skills.tsx index 8fc14741..cda2e5eb 100644 --- a/apps/client/src/pages/builder/sidebars/left/dialogs/skills.tsx +++ b/apps/client/src/pages/builder/sidebars/left/dialogs/skills.tsx @@ -88,10 +88,10 @@ export const SkillsDialog = () => { }} /> - {field.value === 0 ? ( - {t`Hidden`} - ) : ( + {field.value > 0 ? ( {field.value} + ) : ( + {t`Hidden`} )}
diff --git a/apps/client/src/pages/builder/sidebars/left/dialogs/volunteer.tsx b/apps/client/src/pages/builder/sidebars/left/dialogs/volunteer.tsx index 96285fb8..4bfa244a 100644 --- a/apps/client/src/pages/builder/sidebars/left/dialogs/volunteer.tsx +++ b/apps/client/src/pages/builder/sidebars/left/dialogs/volunteer.tsx @@ -112,7 +112,13 @@ export const VolunteerDialog = () => { {...field} content={field.value} footer={(editor) => ( - + { + editor.commands.setContent(value, true); + field.onChange(value); + }} + /> )} onChange={(value) => { field.onChange(value); diff --git a/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx b/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx index 5a618474..edba64c8 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/custom/section.tsx @@ -1,4 +1,4 @@ -import { t } from "@lingui/macro"; +import { t, Trans } from "@lingui/macro"; import { createId } from "@paralleldrive/cuid2"; import { DotsSixVertical, Envelope, Plus, X } from "@phosphor-icons/react"; import { CustomField as ICustomField } from "@reactive-resume/schema"; @@ -37,10 +37,10 @@ export const CustomField = ({ field, onChange, onRemove }: CustomFieldProps) => animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -50 }} > -
+
- + onChange({ ...field, icon: event.target.value }); }} /> + +

+ + Visit{" "} + + Phosphor Icons + {" "} + for a list of available icons + +

{ handleChange("name", event.target.value); }} /> { @@ -87,8 +103,8 @@ export const CustomField = ({ field, onChange, onRemove }: CustomFieldProps) =>
+ + + + {children} diff --git a/apps/client/src/pages/builder/sidebars/left/sections/shared/section-list-item.tsx b/apps/client/src/pages/builder/sidebars/left/sections/shared/section-list-item.tsx index 10085e3a..39f271d5 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/shared/section-list-item.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/shared/section-list-item.tsx @@ -3,11 +3,12 @@ import { CSS } from "@dnd-kit/utilities"; import { t } from "@lingui/macro"; import { CopySimple, DotsSixVertical, PencilSimple, TrashSimple } from "@phosphor-icons/react"; import { - ContextMenu, - ContextMenuCheckboxItem, - ContextMenuContent, - ContextMenuItem, - ContextMenuTrigger, + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, } from "@reactive-resume/ui"; import { cn } from "@reactive-resume/utils"; import { motion } from "framer-motion"; @@ -68,8 +69,8 @@ export const SectionListItem = ({
{/* List Item */} - - + +
{title} {description &&

{description}

}
-
- - + + + {t`Visible`} - - + + + {t`Edit`} - - + + {t`Copy`} - - + + {t`Remove`} - - -
+ + +
); diff --git a/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx b/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx index de30bdad..7e038143 100644 --- a/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx +++ b/apps/client/src/pages/builder/sidebars/left/sections/summary.tsx @@ -32,7 +32,13 @@ export const SummarySection = () => { ( - + { + editor.commands.setContent(value, true); + setValue("sections.summary.content", value); + }} + /> )} onChange={(value) => { setValue("sections.summary.content", value); diff --git a/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/base-card.tsx b/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/base-card.tsx index 6f619f75..2b1bfee1 100644 --- a/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/base-card.tsx +++ b/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/base-card.tsx @@ -1,5 +1,6 @@ import { Card } from "@reactive-resume/ui"; import { cn } from "@reactive-resume/utils"; +import { forwardRef } from "react"; import Tilt from "react-parallax-tilt"; import { defaultTiltProps } from "@/client/constants/parallax-tilt"; @@ -10,16 +11,19 @@ type Props = { children?: React.ReactNode; }; -export const BaseCard = ({ children, className, onClick }: Props) => ( - - - {children} - - +export const BaseCard = forwardRef( + ({ children, className, onClick }, ref) => ( + + + {children} + + + ), ); diff --git a/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx b/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx index f1da2fd9..4eefd04c 100644 --- a/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx +++ b/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx @@ -9,11 +9,11 @@ import { } from "@phosphor-icons/react"; import { ResumeDto } from "@reactive-resume/dto"; import { - ContextMenu, - ContextMenuContent, - ContextMenuItem, - ContextMenuSeparator, - ContextMenuTrigger, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, } from "@reactive-resume/ui"; import { cn } from "@reactive-resume/utils"; import dayjs from "dayjs"; @@ -33,6 +33,7 @@ export const ResumeCard = ({ resume }: Props) => { const { open } = useDialog("resume"); const { open: lockOpen } = useDialog("lock"); + const template = resume.data.metadata.template; const lastUpdated = dayjs().to(resume.updatedAt); const onOpen = () => { @@ -56,9 +57,9 @@ export const ResumeCard = ({ resume }: Props) => { }; return ( - - - + + + {resume.locked && ( {

{resume.title}

{t`Last updated ${lastUpdated}`}

- - - - + {template} + + + + + {t`Open`} - - + + {t`Rename`} - - + + {t`Duplicate`} - + {resume.locked ? ( - + {t`Unlock`} - + ) : ( - + {t`Lock`} - + )} - - + + {t`Delete`} - - - + + + ); }; diff --git a/apps/client/src/pages/dashboard/settings/_sections/openai.tsx b/apps/client/src/pages/dashboard/settings/_sections/openai.tsx index 6f5cdf43..c0dc6aa2 100644 --- a/apps/client/src/pages/dashboard/settings/_sections/openai.tsx +++ b/apps/client/src/pages/dashboard/settings/_sections/openai.tsx @@ -12,7 +12,6 @@ import { FormMessage, Input, } from "@reactive-resume/ui"; -import { cn } from "@reactive-resume/utils"; import { useForm } from "react-hook-form"; import { z } from "zod"; @@ -29,6 +28,7 @@ const formSchema = z.object({ .string() // eslint-disable-next-line lingui/no-unlocalized-strings .regex(/https?:\/\/[^/]+\/?v1$/, "That doesn't look like a valid URL") + .or(z.literal("")) .default(""), model: z.string().default(DEFAULT_MODEL), maxTokens: z.number().default(DEFAULT_MAX_TOKENS), @@ -39,7 +39,8 @@ type FormValues = z.infer; export const OpenAISettings = () => { const { apiKey, setApiKey, baseURL, setBaseURL, model, setModel, maxTokens, setMaxTokens } = useOpenAiStore(); - const isEnabled = !!apiKey || !!baseURL || !!model || !!maxTokens; + + const isEnabled = !!apiKey; const form = useForm({ resolver: zodResolver(formSchema), @@ -75,7 +76,7 @@ export const OpenAISettings = () => { return (
-

{t`OpenAI Integration`}

+

{t`OpenAI/Ollama Integration`}

{t`You can make use of the OpenAI API to help you generate content, or improve your writing while composing your resume.`}

@@ -97,16 +98,13 @@ export const OpenAISettings = () => { from your settings.

-
-

{t`Ollama Integration`}

- -

- You can integrate with Ollama simply by setting the API key to `sk-1234567890abcdef` and - the Base URL to your Ollama URL, i.e. `http://localhost:11434/v1`. You can also pick and - choose models and set the max tokens. + You can also integrate with Ollama simply by setting the API key to + `sk-1234567890abcdef` and the Base URL to your Ollama URL, i.e. + `http://localhost:11434/v1`. You can also pick and choose models and set the max tokens + as per your preference.

@@ -118,7 +116,7 @@ export const OpenAISettings = () => { control={form.control} render={({ field }) => ( - {t`OpenAI / Ollama API Key`} + {t`OpenAI/Ollama API Key`} @@ -172,12 +170,7 @@ export const OpenAISettings = () => { )} /> -
+
- + {hasItems && ( <> diff --git a/apps/client/src/pages/builder/sidebars/right/sections/information.tsx b/apps/client/src/pages/builder/sidebars/right/sections/information.tsx index b5c37165..c5326816 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/information.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/information.tsx @@ -114,7 +114,7 @@ export const InformationSection = () => {
{getSectionIcon("information")} -

{t`Information`}

+

{t`Information`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx b/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx index 7b14f509..ee9b1cd0 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/layout.tsx @@ -204,7 +204,7 @@ export const LayoutSection = () => {
{getSectionIcon("layout")} -

{t`Layout`}

+

{t`Layout`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx b/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx index cc64da68..6e72553c 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/notes.tsx @@ -14,7 +14,7 @@ export const NotesSection = () => {
{getSectionIcon("notes")} -

{t`Notes`}

+

{t`Notes`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/page.tsx b/apps/client/src/pages/builder/sidebars/right/sections/page.tsx index 4e262127..0a0f7d2e 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/page.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/page.tsx @@ -23,7 +23,7 @@ export const PageSection = () => {
{getSectionIcon("page")} -

{t`Page`}

+

{t`Page`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/sharing.tsx b/apps/client/src/pages/builder/sidebars/right/sections/sharing.tsx index 4881786c..0c38cfed 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/sharing.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/sharing.tsx @@ -36,7 +36,7 @@ export const SharingSection = () => {
{getSectionIcon("sharing")} -

{t`Sharing`}

+

{t`Sharing`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/statistics.tsx b/apps/client/src/pages/builder/sidebars/right/sections/statistics.tsx index 91df1787..9092c078 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/statistics.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/statistics.tsx @@ -20,7 +20,7 @@ export const StatisticsSection = () => {
{getSectionIcon("statistics")} -

{t`Statistics`}

+

{t`Statistics`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/template.tsx b/apps/client/src/pages/builder/sidebars/right/sections/template.tsx index e229618e..cba82c2d 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/template.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/template.tsx @@ -16,7 +16,7 @@ export const TemplateSection = () => {
{getSectionIcon("template")} -

{t`Template`}

+

{t`Template`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/theme.tsx b/apps/client/src/pages/builder/sidebars/right/sections/theme.tsx index 37203683..f912d7e6 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/theme.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/theme.tsx @@ -17,7 +17,7 @@ export const ThemeSection = () => {
{getSectionIcon("theme")} -

{t`Theme`}

+

{t`Theme`}

diff --git a/apps/client/src/pages/builder/sidebars/right/sections/typography.tsx b/apps/client/src/pages/builder/sidebars/right/sections/typography.tsx index 1c47c6df..21273e47 100644 --- a/apps/client/src/pages/builder/sidebars/right/sections/typography.tsx +++ b/apps/client/src/pages/builder/sidebars/right/sections/typography.tsx @@ -62,11 +62,11 @@ export const TypographySection = () => {
{getSectionIcon("typography")} -

{t`Typography`}

+

{t`Typography`}

-
+
{fontSuggestions.map((font) => (