fix(client): 🐛 do not allow private resumes to be viewable or downloadable through the link

This commit is contained in:
Amruth Pillai
2023-07-12 15:59:22 +02:00
parent 5ef4bfcb6b
commit 1c2d796c50
121 changed files with 3193 additions and 2068 deletions

View File

@ -63,12 +63,12 @@ const Avatar: React.FC<Props> = ({ size = 64, interactive = true }) => {
<Menu anchorEl={anchorEl} onClose={handleClose} open={Boolean(anchorEl)}>
<MenuItem onClick={handleOpenProfile}>
<div>
<span className="text-xs opacity-50">{t<string>('common.avatar.menu.greeting')},</span>
<span className="text-xs opacity-50">{t('common.avatar.menu.greeting')},</span>
<p>{user?.name}</p>
</div>
</MenuItem>
<Divider />
<MenuItem onClick={handleLogout}>{t<string>('common.avatar.menu.logout')}</MenuItem>
<MenuItem onClick={handleLogout}>{t('common.avatar.menu.logout')}</MenuItem>
</Menu>
</>
);

View File

@ -1,7 +1,7 @@
.content {
@apply rounded px-6 text-sm shadow lg:w-1/2 xl:w-2/5;
@apply absolute inset-4 sm:inset-x-4 sm:inset-y-auto lg:inset-auto;
@apply overflow-scroll bg-neutral-50 dark:bg-neutral-900 lg:overflow-auto;
@apply overflow-scroll bg-zinc-100 dark:bg-zinc-900 lg:overflow-auto;
@apply max-h-[90vh] min-h-fit;
&::-webkit-scrollbar {
@ -10,7 +10,7 @@
}
.header {
@apply sticky top-0 left-0 right-0 z-50 bg-neutral-50 pt-6 dark:bg-neutral-900;
@apply sticky top-0 left-0 right-0 z-50 bg-zinc-100 pt-6 dark:bg-zinc-900;
@apply flex items-center justify-between;
@apply w-full border-b pb-5 dark:border-white/10;
@ -33,7 +33,7 @@
}
.footer {
@apply sticky bottom-0 left-0 right-0 z-50 bg-neutral-50 pb-6 dark:bg-neutral-900;
@apply sticky bottom-0 left-0 right-0 z-50 bg-zinc-100 pb-6 dark:bg-zinc-900;
@apply flex items-center justify-end gap-x-4;
@apply w-full border-t pt-5 dark:border-white/10;
}

View File

@ -0,0 +1,19 @@
import clsx from 'clsx';
type Props = {
className?: string;
};
export const Copyright = ({ className }: Props) => (
<div
className={clsx('prose prose-sm prose-zinc flex flex-col gap-y-1 text-xs opacity-40 dark:prose-invert', className)}
>
<span className="font-medium">v4.0.0</span>
<span>
Licensed under <a href="https://github.com/AmruthPillai/Reactive-Resume/blob/main/LICENSE">MIT</a>
</span>
<span>
A passion project by <a href="https://www.amruthpillai.com/">Amruth Pillai</a>
</span>
</div>
);

View File

@ -10,7 +10,7 @@ const Footer: React.FC<Props> = ({ className }) => {
return (
<div className={clsx('text-xs', className)}>
<p>{t<string>('common.footer.license')}</p>
<p>{t('common.footer.license')}</p>
<p>
<Trans t={t} i18nKey="common.footer.credit">

View File

@ -62,7 +62,7 @@ const Heading: React.FC<Props> = ({
{editMode ? (
<TextField size="small" value={heading} className="w-3/4" onChange={handleChange} />
) : (
<h1>{t<string>(`builder.leftSidebar.${path}.heading`, { defaultValue: heading })}</h1>
<h1>{t(`builder.leftSidebar.${path}.heading`, { defaultValue: heading })}</h1>
)}
</div>
@ -72,19 +72,19 @@ const Heading: React.FC<Props> = ({
})}
>
{isEditable && (
<Tooltip title={t<string>('builder.common.tooltip.rename-section')}>
<Tooltip title={t('builder.common.tooltip.rename-section')}>
<IconButton onClick={toggleEditMode}>{editMode ? <Check /> : <DriveFileRenameOutline />}</IconButton>
</Tooltip>
)}
{isHideable && (
<Tooltip title={t<string>('builder.common.tooltip.toggle-visibility')}>
<Tooltip title={t('builder.common.tooltip.toggle-visibility')}>
<IconButton onClick={toggleVisibility}>{visibility ? <Visibility /> : <VisibilityOff />}</IconButton>
</Tooltip>
)}
{isDeletable && (
<Tooltip title={t<string>('builder.common.tooltip.delete-section')}>
<Tooltip title={t('builder.common.tooltip.delete-section')}>
<IconButton onClick={handleDelete}>
<Delete />
</IconButton>

View File

@ -0,0 +1,27 @@
import clsx from 'clsx';
import Image from 'next/image';
import { useAppSelector } from '@/store/hooks';
type Props = {
className?: string;
size?: 256 | 96 | 64 | 48 | 40 | 32 | 24 | 16;
};
const Icon: React.FC<Props> = ({ size = 64, className }) => {
const theme = useAppSelector((state) => state.build.theme);
const iconTheme = theme === 'light' ? 'dark' : 'light';
return (
<Image
alt="Reactive Resume"
src={`/icon/${iconTheme}.svg`}
className={clsx('rounded', className)}
width={size}
height={size}
priority
/>
);
};
export default Icon;

View File

@ -1,5 +1,5 @@
.container {
@apply rounded-lg border dark:border-neutral-50/10;
@apply rounded-lg border dark:border-zinc-50/10;
.empty {
@apply py-8 text-center;

View File

@ -60,13 +60,13 @@ const List: React.FC<Props> = ({
dispatch(setResumeState({ path, value: newList }));
},
[list, dispatch, path]
[list, dispatch, path],
);
return (
<DndProvider backend={HTML5Backend}>
<div className={clsx(styles.container, className)}>
{isEmpty(list) && <div className={styles.empty}>{t<string>('builder.common.list.empty-text')}</div>}
{isEmpty(list) && <div className={styles.empty}>{t('builder.common.list.empty-text')}</div>}
{list.map((item, index) => {
const title = get(item, titleKey, '');

View File

@ -1,7 +1,7 @@
.item {
@apply flex items-center justify-between;
@apply py-5 pl-5 pr-2;
@apply border-b border-neutral-900/10 last:border-0 dark:border-neutral-50/10;
@apply border-b border-zinc-900/10 last:border-0 dark:border-zinc-50/10;
@apply cursor-move transition-opacity;
.meta {

View File

@ -126,25 +126,25 @@ const ListItem: React.FC<Props> = ({ item, path, index, title, subtitle, onMove,
<ListItemIcon>
<DriveFileRenameOutline className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.common.list.actions.edit')}</ListItemText>
<ListItemText>{t('builder.common.list.actions.edit')}</ListItemText>
</MenuItem>
<MenuItem onClick={() => handleDuplicate(item)}>
<ListItemIcon>
<FileCopy className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.common.list.actions.duplicate')}</ListItemText>
<ListItemText>{t('builder.common.list.actions.duplicate')}</ListItemText>
</MenuItem>
<Divider />
<Tooltip arrow placement="right" title={t<string>('builder.common.tooltip.delete-item')}>
<Tooltip arrow placement="right" title={t('builder.common.tooltip.delete-item')}>
<div>
<MenuItem onClick={() => handleDelete(item)}>
<ListItemIcon>
<DeleteOutline className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.common.list.actions.delete')}</ListItemText>
<ListItemText>{t('builder.common.list.actions.delete')}</ListItemText>
</MenuItem>
</div>
</Tooltip>

View File

@ -1,11 +1,26 @@
import clsx from 'clsx';
import Image from 'next/image';
import { useAppSelector } from '@/store/hooks';
type Props = {
size?: 256 | 64 | 48 | 40 | 32;
className?: string;
size?: 256 | 96 | 64 | 48 | 40 | 32 | 24 | 16;
};
const Logo: React.FC<Props> = ({ size = 64 }) => (
<Image alt="Reactive Resume" src="/images/logos/logo.svg" className="rounded" width={size} height={size} priority />
);
const Logo: React.FC<Props> = ({ size = 64, className }) => {
const theme = useAppSelector((state) => state.build.theme);
return (
<Image
alt="Reactive Resume"
src={`/logo/${theme}.svg`}
className={clsx('rounded', className)}
width={size}
height={size}
priority
/>
);
};
export default Logo;