mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-15 09:11:57 +10:00
fix(client): 🐛 do not allow private resumes to be viewable or downloadable through the link
This commit is contained in:
@ -15,7 +15,7 @@
|
||||
.controller {
|
||||
@apply z-20 flex items-center justify-center shadow-lg;
|
||||
@apply flex rounded-l-full rounded-r-full px-4;
|
||||
@apply bg-neutral-50 dark:bg-neutral-800;
|
||||
@apply bg-zinc-50 dark:bg-zinc-900;
|
||||
@apply opacity-70 transition-opacity duration-200 hover:opacity-100;
|
||||
|
||||
> button {
|
||||
@ -23,6 +23,6 @@
|
||||
}
|
||||
|
||||
> hr {
|
||||
@apply mx-3 h-5 w-0.5 bg-neutral-900/40 dark:bg-neutral-50/20;
|
||||
@apply mx-3 h-5 w-0.5 bg-zinc-900/40 dark:bg-zinc-50/20;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@ import {
|
||||
ZoomOut,
|
||||
} from '@mui/icons-material';
|
||||
import { ButtonBase, Divider, Tooltip, useMediaQuery, useTheme } from '@mui/material';
|
||||
import clsx from 'clsx';
|
||||
import dayjs from 'dayjs';
|
||||
import get from 'lodash/get';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@ -26,6 +25,7 @@ import { printResumeAsPdf, PrintResumeAsPdfParams } from '@/services/printer';
|
||||
import { togglePageBreakLine, togglePageOrientation, toggleSidebar } from '@/store/build/buildSlice';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import getResumeUrl from '@/utils/getResumeUrl';
|
||||
import { cn } from '@/utils/styles';
|
||||
|
||||
import styles from './ArtboardController.module.scss';
|
||||
|
||||
@ -60,7 +60,7 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
|
||||
const url = getResumeUrl(resume, { withHost: true });
|
||||
await navigator.clipboard.writeText(url);
|
||||
|
||||
toast.success(t<string>('common.toast.success.resume-link-copied'));
|
||||
toast.success(t('common.toast.success.resume-link-copied'));
|
||||
};
|
||||
|
||||
const handleExportPDF = async () => {
|
||||
@ -77,40 +77,40 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx({
|
||||
className={cn({
|
||||
[styles.container]: true,
|
||||
[styles.pushLeft]: left.open,
|
||||
[styles.pushRight]: right.open,
|
||||
})}
|
||||
>
|
||||
<div className={styles.controller}>
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.undo')}>
|
||||
<ButtonBase onClick={handleUndo} className={clsx({ 'pointer-events-none opacity-50': past.length < 2 })}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.undo')}>
|
||||
<ButtonBase onClick={handleUndo} className={cn({ 'pointer-events-none opacity-50': past.length < 2 })}>
|
||||
<UndoOutlined fontSize="medium" />
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.redo')}>
|
||||
<ButtonBase onClick={handleRedo} className={clsx({ 'pointer-events-none opacity-50': future.length === 0 })}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.redo')}>
|
||||
<ButtonBase onClick={handleRedo} className={cn({ 'pointer-events-none opacity-50': future.length === 0 })}>
|
||||
<RedoOutlined fontSize="medium" />
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.zoom-in')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.zoom-in')}>
|
||||
<ButtonBase onClick={() => zoomIn(0.25)}>
|
||||
<ZoomIn fontSize="medium" />
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.zoom-out')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.zoom-out')}>
|
||||
<ButtonBase onClick={() => zoomOut(0.25)}>
|
||||
<ZoomOut fontSize="medium" />
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.center-artboard')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.center-artboard')}>
|
||||
<ButtonBase onClick={() => centerView(0.95)}>
|
||||
<FilterCenterFocus fontSize="medium" />
|
||||
</ButtonBase>
|
||||
@ -120,10 +120,10 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
|
||||
|
||||
{isDesktop && (
|
||||
<>
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-orientation')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.toggle-orientation')}>
|
||||
<ButtonBase
|
||||
onClick={handleTogglePageOrientation}
|
||||
className={clsx({ 'pointer-events-none opacity-50': pages.length === 1 })}
|
||||
className={cn({ 'pointer-events-none opacity-50': pages.length === 1 })}
|
||||
>
|
||||
{orientation === 'vertical' ? (
|
||||
<AlignHorizontalCenter fontSize="medium" />
|
||||
@ -133,13 +133,13 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-page-break-line')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.toggle-page-break-line')}>
|
||||
<ButtonBase onClick={handleTogglePageBreakLine}>
|
||||
<InsertPageBreak fontSize="medium" />
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-sidebars')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.toggle-sidebars')}>
|
||||
<ButtonBase onClick={handleToggleSidebar}>
|
||||
<ViewSidebar fontSize="medium" />
|
||||
</ButtonBase>
|
||||
@ -149,13 +149,13 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
|
||||
</>
|
||||
)}
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.copy-link')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.copy-link')}>
|
||||
<ButtonBase onClick={handleCopyLink}>
|
||||
<Link fontSize="medium" />
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.export-pdf')}>
|
||||
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.export-pdf')}>
|
||||
<ButtonBase onClick={handleExportPDF} disabled={isLoading}>
|
||||
<Download fontSize="medium" />
|
||||
</ButtonBase>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
.center {
|
||||
@apply mx-0 flex flex-grow pt-12 lg:pt-16;
|
||||
@apply transition-[margin-left,margin-right] duration-200;
|
||||
@apply bg-neutral-200 dark:bg-neutral-900;
|
||||
@apply bg-zinc-100 dark:bg-zinc-900;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
import { cn } from '@/utils/styles';
|
||||
|
||||
import ArtboardController from './ArtboardController';
|
||||
import styles from './Center.module.scss';
|
||||
@ -19,7 +19,7 @@ const Center = () => {
|
||||
if (isEmpty(resume)) return null;
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.center)}>
|
||||
<div className={cn(styles.center)}>
|
||||
<Header />
|
||||
|
||||
<TransformWrapper
|
||||
@ -35,7 +35,7 @@ const Center = () => {
|
||||
<>
|
||||
<TransformComponent wrapperClass={styles.wrapper}>
|
||||
<div
|
||||
className={clsx({
|
||||
className={cn({
|
||||
[styles.artboard]: true,
|
||||
'flex-col': orientation === 'vertical',
|
||||
})}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
.header {
|
||||
@apply mx-0 flex justify-between shadow;
|
||||
@apply bg-neutral-800 text-neutral-100;
|
||||
@apply bg-zinc-900 text-zinc-100;
|
||||
@apply transition-[margin-left,margin-right] duration-200;
|
||||
|
||||
button > svg {
|
||||
@apply text-base text-neutral-100;
|
||||
@apply text-base text-zinc-100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from '@mui/material';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@ -37,6 +36,7 @@ import { setSidebarState, toggleSidebar } from '@/store/build/buildSlice';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { setModalState } from '@/store/modal/modalSlice';
|
||||
import getResumeUrl from '@/utils/getResumeUrl';
|
||||
import { cn } from '@/utils/styles';
|
||||
|
||||
import styles from './Header.module.scss';
|
||||
|
||||
@ -102,7 +102,7 @@ const Header = () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@ -132,14 +132,14 @@ const Header = () => {
|
||||
const url = getResumeUrl(resume, { withHost: true });
|
||||
await navigator.clipboard.writeText(url);
|
||||
|
||||
toast.success(t<string>('common.toast.success.resume-link-copied'));
|
||||
toast.success(t('common.toast.success.resume-link-copied'));
|
||||
};
|
||||
|
||||
return (
|
||||
<AppBar elevation={0} position="fixed">
|
||||
<Toolbar
|
||||
variant="regular"
|
||||
className={clsx({
|
||||
className={cn({
|
||||
[styles.header]: true,
|
||||
[styles.pushLeft]: left.open,
|
||||
[styles.pushRight]: right.open,
|
||||
@ -165,14 +165,14 @@ const Header = () => {
|
||||
<ListItemIcon>
|
||||
<DriveFileRenameOutline className="scale-90" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t<string>('builder.header.menu.rename')}</ListItemText>
|
||||
<ListItemText>{t('builder.header.menu.rename')}</ListItemText>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem onClick={handleDuplicate}>
|
||||
<ListItemIcon>
|
||||
<CopyAll className="scale-90" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t<string>('builder.header.menu.duplicate')}</ListItemText>
|
||||
<ListItemText>{t('builder.header.menu.duplicate')}</ListItemText>
|
||||
</MenuItem>
|
||||
|
||||
{resume.public ? (
|
||||
@ -180,27 +180,27 @@ const Header = () => {
|
||||
<ListItemIcon>
|
||||
<LinkIcon className="scale-90" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t<string>('builder.header.menu.share-link')}</ListItemText>
|
||||
<ListItemText>{t('builder.header.menu.share-link')}</ListItemText>
|
||||
</MenuItem>
|
||||
) : (
|
||||
<Tooltip arrow placement="right" title={t<string>('builder.header.menu.tooltips.share-link')}>
|
||||
<Tooltip arrow placement="right" title={t('builder.header.menu.tooltips.share-link')}>
|
||||
<div>
|
||||
<MenuItem>
|
||||
<ListItemIcon>
|
||||
<LinkIcon className="scale-90" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t<string>('builder.header.menu.share-link')}</ListItemText>
|
||||
<ListItemText>{t('builder.header.menu.share-link')}</ListItemText>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Tooltip arrow placement="right" title={t<string>('builder.header.menu.tooltips.delete')}>
|
||||
<Tooltip arrow placement="right" title={t('builder.header.menu.tooltips.delete')}>
|
||||
<MenuItem onClick={handleDelete}>
|
||||
<ListItemIcon>
|
||||
<Delete className="scale-90" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t<string>('builder.header.menu.delete')}</ListItemText>
|
||||
<ListItemText>{t('builder.header.menu.delete')}</ListItemText>
|
||||
</MenuItem>
|
||||
</Tooltip>
|
||||
</Menu>
|
||||
|
||||
@ -18,8 +18,8 @@
|
||||
content: 'Page Break';
|
||||
top: calc(297mm - 19px);
|
||||
|
||||
@apply absolute w-full border-b border-dashed border-neutral-800/75;
|
||||
@apply flex items-end justify-end pr-2 pb-0.5 text-xs font-bold text-neutral-800/75;
|
||||
@apply absolute w-full border-b border-dashed border-zinc-900/75;
|
||||
@apply flex items-end justify-end pr-2 pb-0.5 text-xs font-bold text-zinc-900/75;
|
||||
@apply print:hidden;
|
||||
|
||||
:global(.preview-mode) &,
|
||||
|
||||
@ -49,9 +49,7 @@ const Page: React.FC<Props> = ({ page, showPageNumbers = false }) => {
|
||||
{TemplatePage && <TemplatePage page={page} />}
|
||||
</div>
|
||||
|
||||
{showPageNumbers && (
|
||||
<h4 className={styles.pageNumber}>{`${t<string>('builder.common.glossary.page')} ${page + 1}`}</h4>
|
||||
)}
|
||||
{showPageNumbers && <h4 className={styles.pageNumber}>{`${t('builder.common.glossary.page')} ${page + 1}`}</h4>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
.container {
|
||||
@apply h-screen w-[95vw] md:w-[70vw] lg:w-[50vw] xl:w-[30vw] 2xl:w-[28vw];
|
||||
@apply bg-neutral-50 text-neutral-900 dark:bg-neutral-900 dark:text-neutral-50;
|
||||
@apply relative flex border-r-2 border-neutral-50/10;
|
||||
@apply bg-zinc-100 text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100;
|
||||
@apply relative flex border-r-2 border-zinc-100/10;
|
||||
|
||||
nav {
|
||||
@apply absolute inset-y-0 left-0;
|
||||
@apply w-14 py-4 md:w-16 md:px-2;
|
||||
@apply bg-neutral-100 shadow dark:bg-neutral-800;
|
||||
@apply bg-zinc-100 shadow dark:bg-zinc-900;
|
||||
@apply flex flex-col items-center justify-between;
|
||||
|
||||
hr {
|
||||
@ -29,7 +29,7 @@
|
||||
> section {
|
||||
@apply grid gap-4;
|
||||
@apply pt-5 pb-7 first:pt-0;
|
||||
@apply border-b border-neutral-900/10 last:border-b-0 dark:border-neutral-50/10;
|
||||
@apply border-b border-zinc-900/10 last:border-b-0 dark:border-zinc-100/10;
|
||||
|
||||
hr {
|
||||
@apply my-2;
|
||||
|
||||
@ -8,7 +8,7 @@ import React, { ReactComponentElement, useMemo } from 'react';
|
||||
import { Section as SectionRecord } from 'schema';
|
||||
import { validate } from 'uuid';
|
||||
|
||||
import Logo from '@/components/shared/Logo';
|
||||
import Icon from '@/components/shared/Icon';
|
||||
import { getCustomSections, getSectionsByType, left } from '@/config/sections';
|
||||
import { setSidebarState } from '@/store/build/buildSlice';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
@ -69,7 +69,7 @@ const LeftSidebar = () => {
|
||||
sectionsComponents.push(
|
||||
<section key={id} id={id}>
|
||||
{component}
|
||||
</section>
|
||||
</section>,
|
||||
);
|
||||
|
||||
if (addMore) {
|
||||
@ -89,7 +89,7 @@ const LeftSidebar = () => {
|
||||
elements.push(
|
||||
<section key={newId} id={`section-${newId}`}>
|
||||
{newComponent}
|
||||
</section>
|
||||
</section>,
|
||||
);
|
||||
}
|
||||
sectionsComponents.push(...elements);
|
||||
@ -112,7 +112,9 @@ const LeftSidebar = () => {
|
||||
<nav className="overflow-y-auto">
|
||||
<div>
|
||||
<Link href="/dashboard">
|
||||
<Logo size={40} />
|
||||
<IconButton>
|
||||
<Icon size={24} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Divider />
|
||||
</div>
|
||||
@ -123,7 +125,7 @@ const LeftSidebar = () => {
|
||||
arrow
|
||||
key={id}
|
||||
placement="right"
|
||||
title={t<string>(`builder.leftSidebar.sections.${id}.heading`, get(sections, `${id}.name`))}
|
||||
title={t(`builder.leftSidebar.sections.${id}.heading`, get(sections, `${id}.name`))}
|
||||
>
|
||||
<IconButton onClick={() => handleClick(id)}>{icon}</IconButton>
|
||||
</Tooltip>
|
||||
@ -132,7 +134,7 @@ const LeftSidebar = () => {
|
||||
{customSections.map(({ id }) => (
|
||||
<Tooltip
|
||||
key={id}
|
||||
title={t<string>(`builder.leftSidebar.sections.${id}.heading`, get(sections, `${id}.name`))}
|
||||
title={t(`builder.leftSidebar.sections.${id}.heading`, get(sections, `${id}.name`))}
|
||||
placement="right"
|
||||
arrow
|
||||
>
|
||||
@ -157,8 +159,8 @@ const LeftSidebar = () => {
|
||||
|
||||
<div className="py-6 text-right">
|
||||
<Button fullWidth variant="outlined" startIcon={<Add />} onClick={handleAddSection}>
|
||||
{t<string>('builder.common.actions.add', {
|
||||
token: t<string>('builder.leftSidebar.sections.section.heading'),
|
||||
{t('builder.common.actions.add', {
|
||||
token: t('builder.leftSidebar.sections.section.heading'),
|
||||
})}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@ -24,7 +24,7 @@ const Basics = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="sections.basics" name={t<string>('builder.leftSidebar.sections.basics.heading')} />
|
||||
<Heading path="sections.basics" name={t('builder.leftSidebar.sections.basics.heading')} />
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div className="grid items-center gap-4 sm:col-span-2 sm:grid-cols-3">
|
||||
@ -33,10 +33,10 @@ const Basics = () => {
|
||||
</div>
|
||||
|
||||
<div className="grid w-full gap-2 sm:col-span-2">
|
||||
<ResumeInput label={t<string>('builder.leftSidebar.sections.basics.name.label')} path="basics.name" />
|
||||
<ResumeInput label={t('builder.leftSidebar.sections.basics.name.label')} path="basics.name" />
|
||||
|
||||
<Button variant="outlined" startIcon={<PhotoFilter />} onClick={handleClick}>
|
||||
{t<string>('builder.leftSidebar.sections.basics.actions.photo-filters')}
|
||||
{t('builder.leftSidebar.sections.basics.actions.photo-filters')}
|
||||
</Button>
|
||||
|
||||
<Popover
|
||||
@ -59,28 +59,24 @@ const Basics = () => {
|
||||
|
||||
<ResumeInput
|
||||
type="date"
|
||||
label={t<string>('builder.leftSidebar.sections.basics.birthdate.label')}
|
||||
label={t('builder.leftSidebar.sections.basics.birthdate.label')}
|
||||
path="basics.birthdate"
|
||||
className="sm:col-span-2"
|
||||
/>
|
||||
<ResumeInput
|
||||
label={t<string>('builder.common.form.email.label')}
|
||||
path="basics.email"
|
||||
className="sm:col-span-2"
|
||||
/>
|
||||
<ResumeInput label={t<string>('builder.common.form.phone.label')} path="basics.phone" />
|
||||
<ResumeInput label={t<string>('builder.common.form.url.label')} path="basics.website" />
|
||||
<ResumeInput label={t('builder.common.form.email.label')} path="basics.email" className="sm:col-span-2" />
|
||||
<ResumeInput label={t('builder.common.form.phone.label')} path="basics.phone" />
|
||||
<ResumeInput label={t('builder.common.form.url.label')} path="basics.website" />
|
||||
|
||||
<Divider className="sm:col-span-2" />
|
||||
|
||||
<ResumeInput
|
||||
label={t<string>('builder.leftSidebar.sections.basics.headline.label')}
|
||||
label={t('builder.leftSidebar.sections.basics.headline.label')}
|
||||
path="basics.headline"
|
||||
className="sm:col-span-2"
|
||||
/>
|
||||
<ResumeInput
|
||||
type="textarea"
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
path="basics.summary"
|
||||
className="sm:col-span-2"
|
||||
markdownSupported
|
||||
|
||||
@ -8,28 +8,19 @@ const Location = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="sections.location" name={t<string>('builder.leftSidebar.sections.location.heading')} />
|
||||
<Heading path="sections.location" name={t('builder.leftSidebar.sections.location.heading')} />
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<ResumeInput
|
||||
label={t<string>('builder.leftSidebar.sections.location.address.label')}
|
||||
label={t('builder.leftSidebar.sections.location.address.label')}
|
||||
path="basics.location.address"
|
||||
className="sm:col-span-2"
|
||||
/>
|
||||
<ResumeInput label={t('builder.leftSidebar.sections.location.city.label')} path="basics.location.city" />
|
||||
<ResumeInput label={t('builder.leftSidebar.sections.location.region.label')} path="basics.location.region" />
|
||||
<ResumeInput label={t('builder.leftSidebar.sections.location.country.label')} path="basics.location.country" />
|
||||
<ResumeInput
|
||||
label={t<string>('builder.leftSidebar.sections.location.city.label')}
|
||||
path="basics.location.city"
|
||||
/>
|
||||
<ResumeInput
|
||||
label={t<string>('builder.leftSidebar.sections.location.region.label')}
|
||||
path="basics.location.region"
|
||||
/>
|
||||
<ResumeInput
|
||||
label={t<string>('builder.leftSidebar.sections.location.country.label')}
|
||||
path="basics.location.country"
|
||||
/>
|
||||
<ResumeInput
|
||||
label={t<string>('builder.leftSidebar.sections.location.postal-code.label')}
|
||||
label={t('builder.leftSidebar.sections.location.postal-code.label')}
|
||||
path="basics.location.postalCode"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -30,9 +30,9 @@ const PhotoFilters = () => {
|
||||
const handleSetBorder = (value: boolean) => dispatch(setResumeState({ path: 'basics.photo.filters.border', value }));
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 p-5 dark:bg-neutral-800">
|
||||
<div className="flex flex-col gap-2 p-5 dark:bg-zinc-900">
|
||||
<div>
|
||||
<h4 className="font-medium">{t<string>('builder.leftSidebar.sections.basics.photo-filters.size.heading')}</h4>
|
||||
<h4 className="font-medium">{t('builder.leftSidebar.sections.basics.photo-filters.size.heading')}</h4>
|
||||
|
||||
<div className="mx-2">
|
||||
<Slider
|
||||
@ -54,20 +54,18 @@ const PhotoFilters = () => {
|
||||
<Divider />
|
||||
|
||||
<div>
|
||||
<h4 className="font-medium">
|
||||
{t<string>('builder.leftSidebar.sections.basics.photo-filters.effects.heading')}
|
||||
</h4>
|
||||
<h4 className="font-medium">{t('builder.leftSidebar.sections.basics.photo-filters.effects.heading')}</h4>
|
||||
|
||||
<div className="flex items-center">
|
||||
<FormControlLabel
|
||||
label={t<string>('builder.leftSidebar.sections.basics.photo-filters.effects.grayscale.label')}
|
||||
label={t('builder.leftSidebar.sections.basics.photo-filters.effects.grayscale.label')}
|
||||
control={
|
||||
<Checkbox color="secondary" checked={grayscale} onChange={(_, value) => handleSetGrayscale(value)} />
|
||||
}
|
||||
/>
|
||||
|
||||
<FormControlLabel
|
||||
label={t<string>('builder.leftSidebar.sections.basics.photo-filters.effects.border.label')}
|
||||
label={t('builder.leftSidebar.sections.basics.photo-filters.effects.border.label')}
|
||||
control={<Checkbox color="secondary" checked={border} onChange={(_, value) => handleSetBorder(value)} />}
|
||||
/>
|
||||
</div>
|
||||
@ -76,7 +74,7 @@ const PhotoFilters = () => {
|
||||
<Divider />
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<h4 className="font-medium">{t<string>('builder.leftSidebar.sections.basics.photo-filters.shape.heading')}</h4>
|
||||
<h4 className="font-medium">{t('builder.leftSidebar.sections.basics.photo-filters.shape.heading')}</h4>
|
||||
|
||||
<ToggleButtonGroup exclusive value={shape} onChange={(_, value) => handleChangeShape(value)}>
|
||||
<ToggleButton size="small" value="square" className="w-14">
|
||||
|
||||
@ -49,7 +49,7 @@ const PhotoUpload: React.FC = () => {
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (file.size > FILE_UPLOAD_MAX_SIZE) {
|
||||
toast.error(t<string>('common.toast.error.upload-photo-size'));
|
||||
toast.error(t('common.toast.error.upload-photo-size'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -67,8 +67,8 @@ const PhotoUpload: React.FC = () => {
|
||||
<Tooltip
|
||||
title={
|
||||
isEmpty(photo.url)
|
||||
? (t<string>('builder.leftSidebar.sections.basics.photo-upload.tooltip.upload') as string)
|
||||
: (t<string>('builder.leftSidebar.sections.basics.photo-upload.tooltip.remove') as string)
|
||||
? (t('builder.leftSidebar.sections.basics.photo-upload.tooltip.upload') as string)
|
||||
: (t('builder.leftSidebar.sections.basics.photo-upload.tooltip.remove') as string)
|
||||
}
|
||||
>
|
||||
<Avatar sx={{ width: 96, height: 96 }} src={photo.url} />
|
||||
|
||||
@ -28,7 +28,7 @@ const Profiles = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="sections.profiles" name={t<string>('builder.leftSidebar.sections.profiles.heading')} />
|
||||
<Heading path="sections.profiles" name={t('builder.leftSidebar.sections.profiles.heading')} />
|
||||
|
||||
<List
|
||||
path="basics.profiles"
|
||||
@ -40,8 +40,8 @@ const Profiles = () => {
|
||||
|
||||
<footer className="flex justify-end">
|
||||
<Button variant="outlined" startIcon={<Add />} onClick={handleAdd}>
|
||||
{t<string>('builder.common.actions.add', {
|
||||
token: t<string>('builder.leftSidebar.sections.profiles.heading', { count: 1 }),
|
||||
{t('builder.common.actions.add', {
|
||||
token: t('builder.leftSidebar.sections.profiles.heading', { count: 1 }),
|
||||
})}
|
||||
</Button>
|
||||
</footer>
|
||||
|
||||
@ -98,8 +98,8 @@ const Section: React.FC<Props> = ({
|
||||
<SectionSettings path={path} />
|
||||
|
||||
<Button variant="outlined" startIcon={<Add />} onClick={handleAdd}>
|
||||
{t<string>('builder.common.actions.add', {
|
||||
token: t<string>(`builder.leftSidebar.${path}.heading`, { defaultValue: heading }),
|
||||
{t('builder.common.actions.add', {
|
||||
token: t(`builder.leftSidebar.${path}.heading`, { defaultValue: heading }),
|
||||
})}
|
||||
</Button>
|
||||
</footer>
|
||||
@ -107,7 +107,7 @@ const Section: React.FC<Props> = ({
|
||||
{addMore ? (
|
||||
<div className="py-6 text-right">
|
||||
<Button fullWidth variant="outlined" startIcon={<Add />} onClick={handleDuplicateSection}>
|
||||
{t<string>('builder.common.actions.duplicate')}
|
||||
{t('builder.common.actions.duplicate')}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@ -32,7 +32,7 @@ const SectionSettings: React.FC<Props> = ({ path }) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tooltip title={t<string>('builder.common.columns.tooltip')}>
|
||||
<Tooltip title={t('builder.common.columns.tooltip')}>
|
||||
<ButtonBase onClick={handleClick} sx={{ padding: 1, borderRadius: 1 }} className="opacity-50 hover:opacity-75">
|
||||
<ViewWeek /> <span className="ml-1.5 text-xs">{columns}</span>
|
||||
</ButtonBase>
|
||||
@ -47,8 +47,8 @@ const SectionSettings: React.FC<Props> = ({ path }) => {
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<div className="p-5 dark:bg-neutral-800">
|
||||
<h4 className="mb-2 font-medium">{t<string>('builder.common.columns.heading')}</h4>
|
||||
<div className="p-5 dark:bg-zinc-900">
|
||||
<h4 className="mb-2 font-medium">{t('builder.common.columns.heading')}</h4>
|
||||
|
||||
<ToggleButtonGroup exclusive value={columns} onChange={(_, value: number) => handleSetColumns(value)}>
|
||||
{[1, 2, 3, 4].map((index) => (
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
.container {
|
||||
@apply h-screen w-[95vw] md:w-[70vw] lg:w-[50vw] xl:w-[30vw] 2xl:w-[28vw];
|
||||
@apply bg-neutral-50 text-neutral-900 dark:bg-neutral-900 dark:text-neutral-50;
|
||||
@apply relative flex border-l-2 border-neutral-50/10;
|
||||
@apply bg-zinc-50 text-zinc-900 dark:bg-zinc-900 dark:text-zinc-50;
|
||||
@apply relative flex border-l-2 border-zinc-50/10;
|
||||
|
||||
nav {
|
||||
@apply absolute inset-y-0 right-0;
|
||||
@apply w-12 py-4 md:w-16 md:px-2;
|
||||
@apply bg-neutral-100 shadow dark:bg-neutral-800;
|
||||
@apply bg-zinc-100 shadow dark:bg-zinc-900;
|
||||
@apply flex flex-col items-center justify-between;
|
||||
|
||||
hr {
|
||||
@ -29,7 +29,7 @@
|
||||
> section {
|
||||
@apply grid gap-4;
|
||||
@apply pt-5 pb-7 first:pt-0;
|
||||
@apply border-b border-neutral-900/10 last:border-b-0 dark:border-neutral-50/10;
|
||||
@apply border-b border-zinc-900/10 last:border-b-0 dark:border-zinc-50/10;
|
||||
|
||||
hr {
|
||||
@apply my-2;
|
||||
|
||||
@ -45,7 +45,7 @@ const RightSidebar = () => {
|
||||
<div className={styles.container}>
|
||||
<nav className="overflow-y-auto">
|
||||
<div>
|
||||
<Avatar size={40} />
|
||||
<Avatar size={24} />
|
||||
<Divider />
|
||||
</div>
|
||||
|
||||
@ -55,7 +55,7 @@ const RightSidebar = () => {
|
||||
key={id}
|
||||
arrow
|
||||
placement="right"
|
||||
title={t<string>(`builder.rightSidebar.sections.${id}.heading`, { defaultValue: capitalize(id) })}
|
||||
title={t(`builder.rightSidebar.sections.${id}.heading`, { defaultValue: capitalize(id) })}
|
||||
>
|
||||
<IconButton onClick={() => handleClick(id)}>{icon}</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
@ -18,7 +18,7 @@ const CustomCSS = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const customCSS: CustomCSSType = useAppSelector((state) =>
|
||||
get(state.resume.present, 'metadata.css', {} as CustomCSSType)
|
||||
get(state.resume.present, 'metadata.css', {} as CustomCSSType),
|
||||
);
|
||||
|
||||
const handleChange = (value: string | undefined) => {
|
||||
@ -27,7 +27,7 @@ const CustomCSS = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.css" name={t<string>('builder.rightSidebar.sections.css.heading')} isHideable />
|
||||
<Heading path="metadata.css" name={t('builder.rightSidebar.sections.css.heading')} isHideable />
|
||||
|
||||
<Editor
|
||||
height="200px"
|
||||
|
||||
@ -20,12 +20,12 @@ const Export = () => {
|
||||
|
||||
const pdfListItemText = {
|
||||
normal: {
|
||||
primary: t<string>('builder.rightSidebar.sections.export.pdf.normal.primary'),
|
||||
secondary: t<string>('builder.rightSidebar.sections.export.pdf.normal.secondary'),
|
||||
primary: t('builder.rightSidebar.sections.export.pdf.normal.primary'),
|
||||
secondary: t('builder.rightSidebar.sections.export.pdf.normal.secondary'),
|
||||
},
|
||||
loading: {
|
||||
primary: t<string>('builder.rightSidebar.sections.export.pdf.loading.primary'),
|
||||
secondary: t<string>('builder.rightSidebar.sections.export.pdf.loading.secondary'),
|
||||
primary: t('builder.rightSidebar.sections.export.pdf.loading.primary'),
|
||||
secondary: t('builder.rightSidebar.sections.export.pdf.loading.secondary'),
|
||||
},
|
||||
};
|
||||
|
||||
@ -55,7 +55,7 @@ const Export = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.export" name={t<string>('builder.rightSidebar.sections.export.heading')} />
|
||||
<Heading path="metadata.export" name={t('builder.rightSidebar.sections.export.heading')} />
|
||||
|
||||
<List sx={{ padding: 0 }}>
|
||||
<ListItem sx={{ padding: 0 }}>
|
||||
@ -63,8 +63,8 @@ const Export = () => {
|
||||
<Schema />
|
||||
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.export.json.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.export.json.secondary')}
|
||||
primary={t('builder.rightSidebar.sections.export.json.primary')}
|
||||
secondary={t('builder.rightSidebar.sections.export.json.secondary')}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
.page {
|
||||
@apply relative border pl-4 pb-4 dark:border-neutral-100/10;
|
||||
@apply rounded bg-neutral-100 dark:bg-neutral-800;
|
||||
@apply relative border pl-4 pb-4 dark:border-zinc-100/10;
|
||||
@apply rounded bg-zinc-100 dark:bg-zinc-900;
|
||||
|
||||
.delete {
|
||||
@apply opacity-50 hover:opacity-75;
|
||||
@ -28,14 +28,14 @@
|
||||
|
||||
.base {
|
||||
@apply absolute inset-0 w-4/5;
|
||||
@apply rounded bg-neutral-200 dark:bg-neutral-700;
|
||||
@apply rounded bg-zinc-200 dark:bg-zinc-800;
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
@apply relative my-3 w-full px-4 py-2;
|
||||
@apply cursor-move break-all rounded text-xs capitalize;
|
||||
@apply bg-neutral-800/90 text-neutral-50 dark:bg-neutral-50/90 dark:text-neutral-800;
|
||||
@apply bg-zinc-900/90 text-zinc-50 dark:bg-zinc-50/90 dark:text-zinc-900;
|
||||
|
||||
&.disabled {
|
||||
@apply opacity-60;
|
||||
|
||||
@ -60,9 +60,9 @@ const Layout = () => {
|
||||
<>
|
||||
<Heading
|
||||
path="metadata.layout"
|
||||
name={t<string>('builder.rightSidebar.sections.layout.heading')}
|
||||
name={t('builder.rightSidebar.sections.layout.heading')}
|
||||
action={
|
||||
<Tooltip title={t<string>('builder.rightSidebar.sections.layout.tooltip.reset-layout')}>
|
||||
<Tooltip title={t('builder.rightSidebar.sections.layout.tooltip.reset-layout')}>
|
||||
<IconButton onClick={handleResetLayout}>
|
||||
<Restore />
|
||||
</IconButton>
|
||||
@ -76,14 +76,14 @@ const Layout = () => {
|
||||
<div key={pageIndex} className={styles.page}>
|
||||
<div className="flex items-center justify-between pr-3">
|
||||
<p className={styles.heading}>
|
||||
{t<string>('builder.common.glossary.page')} {pageIndex + 1}
|
||||
{t('builder.common.glossary.page')} {pageIndex + 1}
|
||||
</p>
|
||||
|
||||
<div className={clsx(styles.delete, { hidden: pageIndex === 0 })}>
|
||||
<Tooltip
|
||||
title={
|
||||
t<string>('builder.common.actions.delete', {
|
||||
token: t<string>('builder.common.glossary.page'),
|
||||
t('builder.common.actions.delete', {
|
||||
token: t('builder.common.glossary.page'),
|
||||
}) as string
|
||||
}
|
||||
>
|
||||
@ -136,7 +136,7 @@ const Layout = () => {
|
||||
|
||||
<div className="flex items-center justify-end">
|
||||
<Button variant="outlined" startIcon={<Add />} onClick={handleAddPage}>
|
||||
{t<string>('builder.common.actions.add', { token: t<string>('builder.common.glossary.page') })}
|
||||
{t('builder.common.actions.add', { token: t('builder.common.glossary.page') })}
|
||||
</Button>
|
||||
</div>
|
||||
</DragDropContext>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
.section {
|
||||
@apply grid gap-2 rounded p-6;
|
||||
@apply bg-neutral-100 dark:bg-neutral-800;
|
||||
@apply bg-zinc-100 dark:bg-zinc-900;
|
||||
|
||||
h2 {
|
||||
@apply inline-flex items-center gap-2 text-base font-medium;
|
||||
|
||||
@ -12,53 +12,51 @@ const Links = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.links" name={t<string>('builder.rightSidebar.sections.links.heading')} />
|
||||
<Heading path="metadata.links" name={t('builder.rightSidebar.sections.links.heading')} />
|
||||
|
||||
<div className={styles.container}>
|
||||
<div className={styles.section}>
|
||||
<h2>
|
||||
<Savings fontSize="small" />
|
||||
{t<string>('builder.rightSidebar.sections.links.donate.heading')}
|
||||
{t('builder.rightSidebar.sections.links.donate.heading')}
|
||||
</h2>
|
||||
|
||||
<p>{t<string>('builder.rightSidebar.sections.links.donate.body')}</p>
|
||||
<p>{t('builder.rightSidebar.sections.links.donate.body')}</p>
|
||||
|
||||
<a href={DONATION_URL} target="_blank" rel="noreferrer">
|
||||
<Button startIcon={<Coffee />}>{t<string>('builder.rightSidebar.sections.links.donate.button')}</Button>
|
||||
<Button startIcon={<Coffee />}>{t('builder.rightSidebar.sections.links.donate.button')}</Button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<h2>
|
||||
<BugReport fontSize="small" />
|
||||
{t<string>('builder.rightSidebar.sections.links.bugs-features.heading')}
|
||||
{t('builder.rightSidebar.sections.links.bugs-features.heading')}
|
||||
</h2>
|
||||
|
||||
<p>{t<string>('builder.rightSidebar.sections.links.bugs-features.body')}</p>
|
||||
<p>{t('builder.rightSidebar.sections.links.bugs-features.body')}</p>
|
||||
|
||||
<a href={GITHUB_ISSUES_URL} target="_blank" rel="noreferrer">
|
||||
<Button startIcon={<GitHub />}>
|
||||
{t<string>('builder.rightSidebar.sections.links.bugs-features.button')}
|
||||
</Button>
|
||||
<Button startIcon={<GitHub />}>{t('builder.rightSidebar.sections.links.bugs-features.button')}</Button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href={GITHUB_URL} target="_blank" rel="noreferrer">
|
||||
<Button variant="text" startIcon={<Link />}>
|
||||
{t<string>('builder.rightSidebar.sections.links.github')}
|
||||
{t('builder.rightSidebar.sections.links.github')}
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a href={REDDIT_URL} target="_blank" rel="noreferrer">
|
||||
<Button variant="text" startIcon={<Link />}>
|
||||
{t<string>('builder.rightSidebar.sections.links.reddit')}
|
||||
{t('builder.rightSidebar.sections.links.reddit')}
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a href={DOCS_URL} target="_blank" rel="noreferrer">
|
||||
<Button variant="text" startIcon={<Link />}>
|
||||
{t<string>('builder.rightSidebar.sections.links.docs')}
|
||||
{t('builder.rightSidebar.sections.links.docs')}
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -55,7 +55,7 @@ const Settings = () => {
|
||||
const themeString = useMemo(() => (isDarkMode ? 'Matte Black Everything' : 'As bright as your future'), [isDarkMode]);
|
||||
|
||||
const { mutateAsync: loadSampleDataMutation } = useMutation<Resume, ServerError, LoadSampleDataParams>(
|
||||
loadSampleData
|
||||
loadSampleData,
|
||||
);
|
||||
const { mutateAsync: resetResumeMutation } = useMutation<Resume, ServerError, ResetResumeParams>(resetResume);
|
||||
|
||||
@ -96,13 +96,13 @@ const Settings = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.settings" name={t<string>('builder.rightSidebar.sections.settings.heading')} />
|
||||
<Heading path="metadata.settings" name={t('builder.rightSidebar.sections.settings.heading')} />
|
||||
|
||||
<List disablePadding>
|
||||
{/* Global Settings */}
|
||||
<>
|
||||
<ListSubheader disableSticky className="rounded">
|
||||
{t<string>('builder.rightSidebar.sections.settings.global.heading')}
|
||||
{t('builder.rightSidebar.sections.settings.global.heading')}
|
||||
</ListSubheader>
|
||||
|
||||
<ListItem>
|
||||
@ -110,7 +110,7 @@ const Settings = () => {
|
||||
<Palette />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.global.theme.primary')}
|
||||
primary={t('builder.rightSidebar.sections.settings.global.theme.primary')}
|
||||
secondary={themeString}
|
||||
/>
|
||||
<ThemeSwitch checked={isDarkMode} onChange={(_, value: boolean) => handleSetTheme(value)} />
|
||||
@ -119,8 +119,8 @@ const Settings = () => {
|
||||
<ListItem className="flex-col">
|
||||
<ListItemText
|
||||
className="w-full"
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.global.date.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.global.date.secondary')}
|
||||
primary={t('builder.rightSidebar.sections.settings.global.date.primary')}
|
||||
secondary={t('builder.rightSidebar.sections.settings.global.date.secondary')}
|
||||
/>
|
||||
<Autocomplete<string, false, true, false>
|
||||
disableClearable
|
||||
@ -135,8 +135,8 @@ const Settings = () => {
|
||||
<ListItem className="flex-col">
|
||||
<ListItemText
|
||||
className="w-full"
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.global.language.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.global.language.secondary')}
|
||||
primary={t('builder.rightSidebar.sections.settings.global.language.primary')}
|
||||
secondary={t('builder.rightSidebar.sections.settings.global.language.secondary')}
|
||||
/>
|
||||
<Autocomplete<Language, false, true, false>
|
||||
disableClearable
|
||||
@ -160,14 +160,14 @@ const Settings = () => {
|
||||
{/* Page Settings */}
|
||||
<>
|
||||
<ListSubheader disableSticky className="rounded">
|
||||
{t<string>('builder.rightSidebar.sections.settings.page.heading')}
|
||||
{t('builder.rightSidebar.sections.settings.page.heading')}
|
||||
</ListSubheader>
|
||||
|
||||
<ListItem className="flex-col">
|
||||
<ListItemText
|
||||
className="w-full"
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.page.format.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.page.format.secondary')}
|
||||
primary={t('builder.rightSidebar.sections.settings.page.format.primary')}
|
||||
secondary={t('builder.rightSidebar.sections.settings.page.format.secondary')}
|
||||
/>
|
||||
<Autocomplete<PageConfig['format'], false, true, false>
|
||||
disableClearable
|
||||
@ -182,11 +182,11 @@ const Settings = () => {
|
||||
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.page.orientation.primary')}
|
||||
primary={t('builder.rightSidebar.sections.settings.page.orientation.primary')}
|
||||
secondary={
|
||||
pages.length === 1
|
||||
? t<string>('builder.rightSidebar.sections.settings.page.orientation.disabled')
|
||||
: t<string>('builder.rightSidebar.sections.settings.page.orientation.secondary')
|
||||
? t('builder.rightSidebar.sections.settings.page.orientation.disabled')
|
||||
: t('builder.rightSidebar.sections.settings.page.orientation.secondary')
|
||||
}
|
||||
/>
|
||||
<Switch
|
||||
@ -199,8 +199,8 @@ const Settings = () => {
|
||||
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.page.break-line.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.page.break-line.secondary')}
|
||||
primary={t('builder.rightSidebar.sections.settings.page.break-line.primary')}
|
||||
secondary={t('builder.rightSidebar.sections.settings.page.break-line.secondary')}
|
||||
/>
|
||||
<Switch color="secondary" checked={breakLine} onChange={() => dispatch(togglePageBreakLine())} />
|
||||
</ListItem>
|
||||
@ -209,7 +209,7 @@ const Settings = () => {
|
||||
{/* Resume Settings */}
|
||||
<>
|
||||
<ListSubheader disableSticky className="rounded">
|
||||
{t<string>('builder.rightSidebar.sections.settings.resume.heading')}
|
||||
{t('builder.rightSidebar.sections.settings.resume.heading')}
|
||||
</ListSubheader>
|
||||
|
||||
<ListItem disableGutters>
|
||||
@ -218,8 +218,8 @@ const Settings = () => {
|
||||
<Anchor />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.resume.sample.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.resume.sample.secondary')}
|
||||
primary={t('builder.rightSidebar.sections.settings.resume.sample.primary')}
|
||||
secondary={t('builder.rightSidebar.sections.settings.resume.sample.secondary')}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
@ -231,11 +231,9 @@ const Settings = () => {
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={
|
||||
confirmReset
|
||||
? 'Are you sure?'
|
||||
: t<string>('builder.rightSidebar.sections.settings.resume.reset.primary')
|
||||
confirmReset ? 'Are you sure?' : t('builder.rightSidebar.sections.settings.resume.reset.primary')
|
||||
}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.resume.reset.secondary')}
|
||||
secondary={t('builder.rightSidebar.sections.settings.resume.reset.secondary')}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
@ -29,19 +29,19 @@ const Sharing = () => {
|
||||
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
toast.success(t<string>('common.toast.success.resume-link-copied'));
|
||||
toast.success(t('common.toast.success.resume-link-copied'));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.sharing" name={t<string>('builder.rightSidebar.sections.sharing.heading')} />
|
||||
<Heading path="metadata.sharing" name={t('builder.rightSidebar.sections.sharing.heading')} />
|
||||
|
||||
<List sx={{ padding: 0 }}>
|
||||
<ListItem className="flex flex-col" sx={{ padding: 0 }}>
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.sharing.visibility.title')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.sharing.visibility.subtitle')}
|
||||
primary={t('builder.rightSidebar.sections.sharing.visibility.title')}
|
||||
secondary={t('builder.rightSidebar.sections.sharing.visibility.subtitle')}
|
||||
/>
|
||||
<Switch color="secondary" checked={isPublic} onChange={(_, value) => handleSetVisibility(value)} />
|
||||
</div>
|
||||
@ -63,7 +63,7 @@ const Sharing = () => {
|
||||
|
||||
<div className="mt-1 flex w-full">
|
||||
<FormControlLabel
|
||||
label={t<string>('builder.rightSidebar.sections.sharing.short-url.label')}
|
||||
label={t('builder.rightSidebar.sections.sharing.short-url.label')}
|
||||
control={
|
||||
<Checkbox className="mr-1" checked={showShortUrl} onChange={(_, value) => setShowShortUrl(value)} />
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ const Templates = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.templates" name={t<string>('builder.rightSidebar.sections.templates.heading')} />
|
||||
<Heading path="metadata.templates" name={t('builder.rightSidebar.sections.templates.heading')} />
|
||||
|
||||
<div className={styles.container}>
|
||||
{Object.values(templateMap).map((template) => (
|
||||
|
||||
@ -17,7 +17,7 @@ const Theme = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { background, text, primary } = useAppSelector<ThemeConfig>((state) =>
|
||||
get(state.resume.present, 'metadata.theme')
|
||||
get(state.resume.present, 'metadata.theme'),
|
||||
);
|
||||
|
||||
const handleChange = (property: string, color: string) => {
|
||||
@ -26,7 +26,7 @@ const Theme = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.theme" name={t<string>('builder.rightSidebar.sections.theme.heading')} />
|
||||
<Heading path="metadata.theme" name={t('builder.rightSidebar.sections.theme.heading')} />
|
||||
|
||||
<div className={styles.container}>
|
||||
<div className={styles.colorOptions}>
|
||||
@ -36,18 +36,18 @@ const Theme = () => {
|
||||
</div>
|
||||
|
||||
<ColorPicker
|
||||
label={t<string>('builder.rightSidebar.sections.theme.form.primary.label')}
|
||||
label={t('builder.rightSidebar.sections.theme.form.primary.label')}
|
||||
color={primary}
|
||||
className="col-span-2"
|
||||
onChange={(color) => handleChange('primary', color)}
|
||||
/>
|
||||
<ColorPicker
|
||||
label={t<string>('builder.rightSidebar.sections.theme.form.background.label')}
|
||||
label={t('builder.rightSidebar.sections.theme.form.background.label')}
|
||||
color={background}
|
||||
onChange={(color) => handleChange('background', color)}
|
||||
/>
|
||||
<ColorPicker
|
||||
label={t<string>('builder.rightSidebar.sections.theme.form.text.label')}
|
||||
label={t('builder.rightSidebar.sections.theme.form.text.label')}
|
||||
color={text}
|
||||
onChange={(color) => handleChange('text', color)}
|
||||
/>
|
||||
|
||||
@ -46,7 +46,7 @@ const Widgets: React.FC<WidgetProps> = ({ label, category }) => {
|
||||
setResumeState({
|
||||
path: `metadata.typography.${property}.${category}`,
|
||||
value: property === 'family' ? (value as Font).family : value,
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@ -64,7 +64,7 @@ const Widgets: React.FC<WidgetProps> = ({ label, category }) => {
|
||||
step={1}
|
||||
marks={[
|
||||
{ value: 12, label: '12px' },
|
||||
{ value: 24, label: t<string>('builder.rightSidebar.sections.typography.form.font-size.label') },
|
||||
{ value: 24, label: t('builder.rightSidebar.sections.typography.form.font-size.label') },
|
||||
{ value: 36, label: '36px' },
|
||||
]}
|
||||
valueLabelDisplay="auto"
|
||||
@ -82,10 +82,7 @@ const Widgets: React.FC<WidgetProps> = ({ label, category }) => {
|
||||
value={fonts.find((font) => font.family === family[category])}
|
||||
onChange={(_, font: Font | null) => handleChange('family', font)}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label={t<string>('builder.rightSidebar.sections.typography.form.font-family.label')}
|
||||
/>
|
||||
<TextField {...params} label={t('builder.rightSidebar.sections.typography.form.font-family.label')} />
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
@ -98,13 +95,10 @@ const Typography = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path="metadata.typography" name={t<string>('builder.rightSidebar.sections.typography.heading')} />
|
||||
<Heading path="metadata.typography" name={t('builder.rightSidebar.sections.typography.heading')} />
|
||||
|
||||
<Widgets
|
||||
label={t<string>('builder.rightSidebar.sections.typography.widgets.headings.label')}
|
||||
category="heading"
|
||||
/>
|
||||
<Widgets label={t<string>('builder.rightSidebar.sections.typography.widgets.body.label')} category="body" />
|
||||
<Widgets label={t('builder.rightSidebar.sections.typography.widgets.headings.label')} category="heading" />
|
||||
<Widgets label={t('builder.rightSidebar.sections.typography.widgets.body.label')} category="body" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user