mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-14 00:32:35 +10:00
fix(client): 🐛 do not allow private resumes to be viewable or downloadable through the link
This commit is contained in:
@ -54,16 +54,16 @@ const ForgotPasswordModal: React.FC = () => {
|
||||
<BaseModal
|
||||
icon={<Password />}
|
||||
isOpen={isOpen}
|
||||
heading={t<string>('modals.auth.forgot-password.heading')}
|
||||
heading={t('modals.auth.forgot-password.heading')}
|
||||
handleClose={handleClose}
|
||||
footerChildren={
|
||||
<Button type="submit" disabled={isLoading} onClick={handleSubmit(onSubmit)}>
|
||||
{t<string>('modals.auth.forgot-password.actions.send-email')}
|
||||
{t('modals.auth.forgot-password.actions.send-email')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<div className="grid gap-4">
|
||||
<p>{t<string>('modals.auth.forgot-password.body')}</p>
|
||||
<p>{t('modals.auth.forgot-password.body')}</p>
|
||||
|
||||
<form className="grid gap-4 xl:w-2/3">
|
||||
<Controller
|
||||
@ -72,7 +72,7 @@ const ForgotPasswordModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
autoFocus
|
||||
label={t<string>('modals.auth.forgot-password.form.email.label')}
|
||||
label={t('modals.auth.forgot-password.form.email.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -81,7 +81,7 @@ const ForgotPasswordModal: React.FC = () => {
|
||||
/>
|
||||
</form>
|
||||
|
||||
<p className="text-xs">{t<string>('modals.auth.forgot-password.help-text')}</p>
|
||||
<p className="text-xs">{t('modals.auth.forgot-password.help-text')}</p>
|
||||
</div>
|
||||
</BaseModal>
|
||||
</>
|
||||
|
||||
@ -53,7 +53,7 @@ const LoginModal: React.FC = () => {
|
||||
const { mutateAsync: loginMutation } = useMutation<void, ServerError, LoginParams>(login);
|
||||
|
||||
const { mutateAsync: loginWithGoogleMutation } = useMutation<void, ServerError, LoginWithGoogleParams>(
|
||||
loginWithGoogle
|
||||
loginWithGoogle,
|
||||
);
|
||||
|
||||
const handleClose = () => {
|
||||
@ -105,7 +105,7 @@ const LoginModal: React.FC = () => {
|
||||
<BaseModal
|
||||
icon={<Login />}
|
||||
isOpen={isOpen}
|
||||
heading={t<string>('modals.auth.login.heading')}
|
||||
heading={t('modals.auth.login.heading')}
|
||||
handleClose={handleClose}
|
||||
footerChildren={
|
||||
<div className="flex gap-4">
|
||||
@ -114,12 +114,12 @@ const LoginModal: React.FC = () => {
|
||||
)}
|
||||
|
||||
<Button type="submit" onClick={handleSubmit(onSubmit)} disabled={isLoading}>
|
||||
{t<string>('modals.auth.login.actions.login')}
|
||||
{t('modals.auth.login.actions.login')}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<p>{t<string>('modals.auth.login.body')}</p>
|
||||
<p>{t('modals.auth.login.body')}</p>
|
||||
|
||||
<form className="grid gap-4 xl:w-2/3">
|
||||
<Controller
|
||||
@ -128,9 +128,9 @@ const LoginModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
autoFocus
|
||||
label={t<string>('modals.auth.login.form.username.label')}
|
||||
label={t('modals.auth.login.form.username.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || t<string>('modals.auth.login.form.username.help-text')}
|
||||
helperText={fieldState.error?.message || t('modals.auth.login.form.username.help-text')}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
@ -142,7 +142,7 @@ const LoginModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
label={t<string>('modals.auth.login.form.password.label')}
|
||||
label={t('modals.auth.login.form.password.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
InputProps={{ endAdornment: <PasswordVisibility /> }}
|
||||
|
||||
@ -61,7 +61,7 @@ const RegisterModal: React.FC = () => {
|
||||
const { mutateAsync, isLoading } = useMutation<void, ServerError, RegisterParams>(registerUser);
|
||||
|
||||
const { mutateAsync: loginWithGoogleMutation } = useMutation<void, ServerError, LoginWithGoogleParams>(
|
||||
loginWithGoogle
|
||||
loginWithGoogle,
|
||||
);
|
||||
|
||||
const handleClose = () => {
|
||||
@ -95,7 +95,7 @@ const RegisterModal: React.FC = () => {
|
||||
<BaseModal
|
||||
icon={<HowToReg />}
|
||||
isOpen={isOpen}
|
||||
heading={t<string>('modals.auth.register.heading')}
|
||||
heading={t('modals.auth.register.heading')}
|
||||
handleClose={handleClose}
|
||||
footerChildren={
|
||||
<div className="flex gap-4">
|
||||
@ -104,12 +104,12 @@ const RegisterModal: React.FC = () => {
|
||||
)}
|
||||
|
||||
<Button type="submit" onClick={handleSubmit(onSubmit)} disabled={isLoading}>
|
||||
{t<string>('modals.auth.register.actions.register')}
|
||||
{t('modals.auth.register.actions.register')}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<p>{t<string>('modals.auth.register.body')}</p>
|
||||
<p>{t('modals.auth.register.body')}</p>
|
||||
|
||||
<form className="grid gap-4 md:grid-cols-2">
|
||||
<Controller
|
||||
@ -118,7 +118,7 @@ const RegisterModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
autoFocus
|
||||
label={t<string>('modals.auth.register.form.name.label')}
|
||||
label={t('modals.auth.register.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -131,7 +131,7 @@ const RegisterModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('modals.auth.register.form.username.label')}
|
||||
label={t('modals.auth.register.form.username.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -145,7 +145,7 @@ const RegisterModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
type="email"
|
||||
label={t<string>('modals.auth.register.form.email.label')}
|
||||
label={t('modals.auth.register.form.email.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
@ -160,7 +160,7 @@ const RegisterModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
type="password"
|
||||
label={t<string>('modals.auth.register.form.password.label')}
|
||||
label={t('modals.auth.register.form.password.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -174,7 +174,7 @@ const RegisterModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
type="password"
|
||||
label={t<string>('modals.auth.register.form.confirm-password.label')}
|
||||
label={t('modals.auth.register.form.confirm-password.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
|
||||
@ -65,15 +65,15 @@ const ResetPasswordModal: React.FC = () => {
|
||||
<BaseModal
|
||||
icon={<LockReset />}
|
||||
isOpen={isOpen}
|
||||
heading={t<string>('modals.auth.reset-password.heading')}
|
||||
heading={t('modals.auth.reset-password.heading')}
|
||||
handleClose={handleClose}
|
||||
footerChildren={
|
||||
<Button type="submit" disabled={isLoading} onClick={handleSubmit(onSubmit)}>
|
||||
{t<string>('modals.auth.reset-password.actions.set-password')}
|
||||
{t('modals.auth.reset-password.actions.set-password')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<p>{t<string>('modals.auth.reset-password.body')}</p>
|
||||
<p>{t('modals.auth.reset-password.body')}</p>
|
||||
|
||||
<form className="grid gap-4 md:grid-cols-2">
|
||||
<Controller
|
||||
@ -83,7 +83,7 @@ const ResetPasswordModal: React.FC = () => {
|
||||
<TextField
|
||||
autoFocus
|
||||
type="password"
|
||||
label={t<string>('modals.auth.reset-password.form.password.label')}
|
||||
label={t('modals.auth.reset-password.form.password.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -97,7 +97,7 @@ const ResetPasswordModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
type="password"
|
||||
label={t<string>('modals.auth.reset-password.form.confirm-password.label')}
|
||||
label={t('modals.auth.reset-password.form.confirm-password.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
|
||||
@ -89,7 +89,7 @@ const UserProfileModal = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
autoFocus
|
||||
label={t<string>('modals.auth.profile.form.name.label')}
|
||||
label={t('modals.auth.profile.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -114,16 +114,16 @@ const UserProfileModal = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
disabled
|
||||
label={t<string>('modals.auth.profile.form.email.label')}
|
||||
label={t('modals.auth.profile.form.email.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={t<string>('modals.auth.profile.form.email.help-text')}
|
||||
helperText={t('modals.auth.profile.form.email.help-text')}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<Button onClick={handleUpdate}>{t<string>('modals.auth.profile.actions.save')}</Button>
|
||||
<Button onClick={handleUpdate}>{t('modals.auth.profile.actions.save')}</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -133,12 +133,10 @@ const UserProfileModal = () => {
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<CrisisAlert />
|
||||
<h5 className="font-medium">{t<string>('modals.auth.profile.delete-account.heading')}</h5>
|
||||
<h5 className="font-medium">{t('modals.auth.profile.delete-account.heading')}</h5>
|
||||
</div>
|
||||
|
||||
<p className="text-xs opacity-75">
|
||||
{t<string>('modals.auth.profile.delete-account.body', { keyword: 'delete' })}
|
||||
</p>
|
||||
<p className="text-xs opacity-75">{t('modals.auth.profile.delete-account.body', { keyword: 'delete' })}</p>
|
||||
|
||||
<div className="flex max-w-xs flex-col gap-4">
|
||||
<TextField
|
||||
@ -149,7 +147,7 @@ const UserProfileModal = () => {
|
||||
|
||||
<div>
|
||||
<Button variant="contained" color="error" disabled={!isDeleteTextValid} onClick={handleDelete}>
|
||||
{t<string>('modals.auth.profile.delete-account.actions.delete')}
|
||||
{t('modals.auth.profile.delete-account.actions.delete')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -50,8 +50,8 @@ const AwardModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -73,7 +73,7 @@ const AwardModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -101,7 +101,7 @@ const AwardModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.title.label')}
|
||||
label={t('builder.common.form.title.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -115,7 +115,7 @@ const AwardModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.leftSidebar.sections.awards.form.awarder.label')}
|
||||
label={t('builder.leftSidebar.sections.awards.form.awarder.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -130,7 +130,7 @@ const AwardModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.date.label')}
|
||||
label={t('builder.common.form.date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -154,7 +154,7 @@ const AwardModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
@ -171,7 +171,7 @@ const AwardModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
|
||||
@ -50,8 +50,8 @@ const CertificateModal: React.FC = () => {
|
||||
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -73,7 +73,7 @@ const CertificateModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -101,7 +101,7 @@ const CertificateModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.name.label')}
|
||||
label={t('builder.common.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -115,7 +115,7 @@ const CertificateModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.leftSidebar.sections.certifications.form.issuer.label')}
|
||||
label={t('builder.leftSidebar.sections.certifications.form.issuer.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -130,7 +130,7 @@ const CertificateModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.date.label')}
|
||||
label={t('builder.common.form.date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -154,7 +154,7 @@ const CertificateModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
@ -171,7 +171,7 @@ const CertificateModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
|
||||
@ -2,7 +2,6 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, Slider, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { Custom } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
@ -10,6 +9,7 @@ import isEmpty from 'lodash/isEmpty';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { Custom } from 'schema';
|
||||
|
||||
import ArrayInput from '@/components/shared/ArrayInput';
|
||||
import BaseModal from '@/components/shared/BaseModal';
|
||||
@ -68,8 +68,8 @@ const CustomModal: React.FC = () => {
|
||||
|
||||
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -91,7 +91,7 @@ const CustomModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: 'builder.sections.custom',
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -119,7 +119,7 @@ const CustomModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.title.label')}
|
||||
label={t('builder.common.form.title.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -132,7 +132,7 @@ const CustomModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.subtitle.label')}
|
||||
label={t('builder.common.form.subtitle.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -147,7 +147,7 @@ const CustomModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.start-date.label')}
|
||||
label={t('builder.common.form.start-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -173,7 +173,7 @@ const CustomModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.end-date.label')}
|
||||
label={t('builder.common.form.end-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -181,7 +181,7 @@ const CustomModal: React.FC = () => {
|
||||
<TextField
|
||||
{...params}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || t<string>('builder.common.form.end-date.help-text')}
|
||||
helperText={fieldState.error?.message || t('builder.common.form.end-date.help-text')}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
@ -197,7 +197,7 @@ const CustomModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
@ -212,7 +212,7 @@ const CustomModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.level.label')}
|
||||
label={t('builder.common.form.level.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
@ -226,11 +226,13 @@ const CustomModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<div className="col-span-2">
|
||||
<h4 className="mb-3 font-semibold">{t<string>('builder.common.form.levelNum.label')}</h4>
|
||||
<h4 className="mb-3 font-semibold">{t('builder.common.form.levelNum.label')}</h4>
|
||||
|
||||
<div className="px-10">
|
||||
<Slider
|
||||
{...field}
|
||||
name={field.name}
|
||||
value={field.value}
|
||||
onChange={(_, value) => field.onChange(value as number)}
|
||||
marks={[
|
||||
{
|
||||
value: 0,
|
||||
@ -250,7 +252,7 @@ const CustomModal: React.FC = () => {
|
||||
defaultValue={0}
|
||||
color="secondary"
|
||||
valueLabelDisplay="auto"
|
||||
aria-label={t<string>('builder.common.form.levelNum.label')}
|
||||
aria-label={t('builder.common.form.levelNum.label')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -267,7 +269,7 @@ const CustomModal: React.FC = () => {
|
||||
maxRows={6}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
{...field}
|
||||
/>
|
||||
@ -279,7 +281,7 @@ const CustomModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<ArrayInput
|
||||
label={t<string>('builder.common.form.keywords.label')}
|
||||
label={t('builder.common.form.keywords.label')}
|
||||
value={field.value as string[]}
|
||||
onChange={field.onChange}
|
||||
errors={fieldState.error}
|
||||
|
||||
@ -63,8 +63,8 @@ const EducationModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -86,7 +86,7 @@ const EducationModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -114,7 +114,7 @@ const EducationModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.leftSidebar.sections.education.form.institution.label')}
|
||||
label={t('builder.leftSidebar.sections.education.form.institution.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -128,7 +128,7 @@ const EducationModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.leftSidebar.sections.education.form.degree.label')}
|
||||
label={t('builder.leftSidebar.sections.education.form.degree.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -141,7 +141,7 @@ const EducationModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.leftSidebar.sections.education.form.area-study.label')}
|
||||
label={t('builder.leftSidebar.sections.education.form.area-study.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -154,7 +154,7 @@ const EducationModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.leftSidebar.sections.education.form.grade.label')}
|
||||
label={t('builder.leftSidebar.sections.education.form.grade.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -169,7 +169,7 @@ const EducationModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.start-date.label')}
|
||||
label={t('builder.common.form.start-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -195,7 +195,7 @@ const EducationModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.end-date.label')}
|
||||
label={t('builder.common.form.end-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -203,7 +203,7 @@ const EducationModal: React.FC = () => {
|
||||
<TextField
|
||||
{...params}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || t<string>('builder.common.form.end-date.help-text')}
|
||||
helperText={fieldState.error?.message || t('builder.common.form.end-date.help-text')}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
@ -219,7 +219,7 @@ const EducationModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
@ -237,7 +237,7 @@ const EducationModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
@ -251,7 +251,7 @@ const EducationModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<ArrayInput
|
||||
label={t<string>('builder.leftSidebar.sections.education.form.courses.label')}
|
||||
label={t('builder.leftSidebar.sections.education.form.courses.label')}
|
||||
value={field.value as string[]}
|
||||
onChange={field.onChange}
|
||||
errors={fieldState.error}
|
||||
|
||||
@ -41,8 +41,8 @@ const InterestModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -64,7 +64,7 @@ const InterestModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -92,7 +92,7 @@ const InterestModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.name.label')}
|
||||
label={t('builder.common.form.name.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
@ -106,7 +106,7 @@ const InterestModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<ArrayInput
|
||||
label={t<string>('builder.common.form.keywords.label')}
|
||||
label={t('builder.common.form.keywords.label')}
|
||||
value={field.value as string[]}
|
||||
onChange={field.onChange}
|
||||
errors={fieldState.error}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, Slider, TextField } from '@mui/material';
|
||||
import { Language, SectionPath } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { Language, SectionPath } from 'schema';
|
||||
|
||||
import BaseModal from '@/components/shared/BaseModal';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
@ -42,8 +42,8 @@ const LanguageModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -65,7 +65,7 @@ const LanguageModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -93,7 +93,7 @@ const LanguageModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.name.label')}
|
||||
label={t('builder.common.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -107,7 +107,7 @@ const LanguageModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.common.form.level.label')}
|
||||
label={t('builder.common.form.level.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -120,11 +120,13 @@ const LanguageModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<div className="col-span-2">
|
||||
<h4 className="mb-3 font-semibold">{t<string>('builder.common.form.levelNum.label')}</h4>
|
||||
<h4 className="mb-3 font-semibold">{t('builder.common.form.levelNum.label')}</h4>
|
||||
|
||||
<div className="px-10">
|
||||
<Slider
|
||||
{...field}
|
||||
name={field.name}
|
||||
value={field.value}
|
||||
onChange={(_, value) => field.onChange(value as number)}
|
||||
marks={[
|
||||
{
|
||||
value: 0,
|
||||
@ -144,7 +146,7 @@ const LanguageModal: React.FC = () => {
|
||||
defaultValue={0}
|
||||
color="secondary"
|
||||
valueLabelDisplay="auto"
|
||||
aria-label={t<string>('builder.common.form.levelNum.label')}
|
||||
aria-label={t('builder.common.form.levelNum.label')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -42,11 +42,11 @@ const ProfileModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = t<string>('builder.common.actions.add', {
|
||||
token: t<string>('builder.leftSidebar.sections.profiles.heading', { count: 1 }),
|
||||
const addText = t('builder.common.actions.add', {
|
||||
token: t('builder.leftSidebar.sections.profiles.heading', { count: 1 }),
|
||||
});
|
||||
const editText = t<string>('builder.common.actions.edit', {
|
||||
token: t<string>('builder.leftSidebar.sections.profiles.heading', { count: 1 }),
|
||||
const editText = t('builder.common.actions.edit', {
|
||||
token: t('builder.leftSidebar.sections.profiles.heading', { count: 1 }),
|
||||
});
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
@ -69,7 +69,7 @@ const ProfileModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -97,7 +97,7 @@ const ProfileModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.leftSidebar.sections.profiles.form.network.label')}
|
||||
label={t('builder.leftSidebar.sections.profiles.form.network.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -111,7 +111,7 @@ const ProfileModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.leftSidebar.sections.profiles.form.username.label')}
|
||||
label={t('builder.leftSidebar.sections.profiles.form.username.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
InputProps={{
|
||||
@ -127,7 +127,7 @@ const ProfileModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
className="col-span-2"
|
||||
placeholder="https://"
|
||||
error={!!fieldState.error}
|
||||
|
||||
@ -59,8 +59,8 @@ const ProjectModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -82,7 +82,7 @@ const ProjectModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -110,7 +110,7 @@ const ProjectModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.name.label')}
|
||||
label={t('builder.common.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -124,7 +124,7 @@ const ProjectModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.common.form.description.label')}
|
||||
label={t('builder.common.form.description.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -139,7 +139,7 @@ const ProjectModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.start-date.label')}
|
||||
label={t('builder.common.form.start-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -165,7 +165,7 @@ const ProjectModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.end-date.label')}
|
||||
label={t('builder.common.form.end-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -173,7 +173,7 @@ const ProjectModal: React.FC = () => {
|
||||
<TextField
|
||||
{...params}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || t<string>('builder.common.form.end-date.help-text')}
|
||||
helperText={fieldState.error?.message || t('builder.common.form.end-date.help-text')}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
@ -189,7 +189,7 @@ const ProjectModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
@ -207,7 +207,7 @@ const ProjectModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
@ -221,7 +221,7 @@ const ProjectModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<ArrayInput
|
||||
label={t<string>('builder.common.form.keywords.label')}
|
||||
label={t('builder.common.form.keywords.label')}
|
||||
value={field.value as string[]}
|
||||
onChange={field.onChange}
|
||||
errors={fieldState.error}
|
||||
|
||||
@ -50,8 +50,8 @@ const PublicationModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -73,7 +73,7 @@ const PublicationModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -101,7 +101,7 @@ const PublicationModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.name.label')}
|
||||
label={t('builder.common.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -115,7 +115,7 @@ const PublicationModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.leftSidebar.sections.publications.form.publisher.label')}
|
||||
label={t('builder.leftSidebar.sections.publications.form.publisher.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -130,7 +130,7 @@ const PublicationModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.date.label')}
|
||||
label={t('builder.common.form.date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -154,7 +154,7 @@ const PublicationModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
@ -171,7 +171,7 @@ const PublicationModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
|
||||
@ -47,8 +47,8 @@ const ReferenceModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -70,7 +70,7 @@ const ReferenceModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -98,7 +98,7 @@ const ReferenceModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.name.label')}
|
||||
label={t('builder.common.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -112,7 +112,7 @@ const ReferenceModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.leftSidebar.sections.references.form.relationship.label')}
|
||||
label={t('builder.leftSidebar.sections.references.form.relationship.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -125,7 +125,7 @@ const ReferenceModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.phone.label')}
|
||||
label={t('builder.common.form.phone.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -138,7 +138,7 @@ const ReferenceModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.email.label')}
|
||||
label={t('builder.common.form.email.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -154,7 +154,7 @@ const ReferenceModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, Slider, TextField } from '@mui/material';
|
||||
import { SectionPath, Skill } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { SectionPath, Skill } from 'schema';
|
||||
|
||||
import ArrayInput from '@/components/shared/ArrayInput';
|
||||
import BaseModal from '@/components/shared/BaseModal';
|
||||
@ -45,8 +45,8 @@ const SkillModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -68,7 +68,7 @@ const SkillModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -96,7 +96,7 @@ const SkillModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.common.form.name.label')}
|
||||
label={t('builder.common.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -109,7 +109,7 @@ const SkillModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.level.label')}
|
||||
label={t('builder.common.form.level.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -122,11 +122,13 @@ const SkillModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<div className="col-span-2">
|
||||
<h4 className="mb-3 font-semibold">{t<string>('builder.common.form.levelNum.label')}</h4>
|
||||
<h4 className="mb-3 font-semibold">{t('builder.common.form.levelNum.label')}</h4>
|
||||
|
||||
<div className="px-3">
|
||||
<Slider
|
||||
{...field}
|
||||
name={field.name}
|
||||
value={field.value}
|
||||
onChange={(_, value) => field.onChange(value as number)}
|
||||
marks={[
|
||||
{
|
||||
value: 0,
|
||||
@ -146,7 +148,7 @@ const SkillModal: React.FC = () => {
|
||||
defaultValue={0}
|
||||
color="secondary"
|
||||
valueLabelDisplay="auto"
|
||||
aria-label={t<string>('builder.common.form.levelNum.label')}
|
||||
aria-label={t('builder.common.form.levelNum.label')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -158,7 +160,7 @@ const SkillModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<ArrayInput
|
||||
label={t<string>('builder.common.form.keywords.label')}
|
||||
label={t('builder.common.form.keywords.label')}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
errors={fieldState.error}
|
||||
|
||||
@ -56,8 +56,8 @@ const VolunteerModal: React.FC = () => {
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
const addText = useMemo(() => t('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
defaultValues: defaultState,
|
||||
@ -79,7 +79,7 @@ const VolunteerModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -107,7 +107,7 @@ const VolunteerModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.leftSidebar.sections.volunteer.form.organization.label')}
|
||||
label={t('builder.leftSidebar.sections.volunteer.form.organization.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -121,7 +121,7 @@ const VolunteerModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.common.form.position.label')}
|
||||
label={t('builder.common.form.position.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -136,7 +136,7 @@ const VolunteerModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.start-date.label')}
|
||||
label={t('builder.common.form.start-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -162,7 +162,7 @@ const VolunteerModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.end-date.label')}
|
||||
label={t('builder.common.form.end-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -170,7 +170,7 @@ const VolunteerModal: React.FC = () => {
|
||||
<TextField
|
||||
{...params}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || t<string>('builder.common.form.end-date.help-text')}
|
||||
helperText={fieldState.error?.message || t('builder.common.form.end-date.help-text')}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
@ -186,7 +186,7 @@ const VolunteerModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
@ -204,7 +204,7 @@ const VolunteerModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
|
||||
@ -58,17 +58,17 @@ const WorkModal: React.FC = () => {
|
||||
|
||||
const addText = useMemo(
|
||||
() =>
|
||||
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 }),
|
||||
}),
|
||||
[t, heading]
|
||||
[t, heading],
|
||||
);
|
||||
const editText = useMemo(
|
||||
() =>
|
||||
t<string>('builder.common.actions.edit', {
|
||||
token: t<string>(`builder.leftSidebar.${path}.heading`, { defaultValue: heading }),
|
||||
t('builder.common.actions.edit', {
|
||||
token: t(`builder.leftSidebar.${path}.heading`, { defaultValue: heading }),
|
||||
}),
|
||||
[t, heading]
|
||||
[t, heading],
|
||||
);
|
||||
|
||||
const { reset, control, handleSubmit } = useForm<FormData>({
|
||||
@ -91,7 +91,7 @@ const WorkModal: React.FC = () => {
|
||||
setModalState({
|
||||
modal: 'builder.sections.work',
|
||||
state: { open: false },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
reset(defaultState);
|
||||
@ -119,7 +119,7 @@ const WorkModal: React.FC = () => {
|
||||
<TextField
|
||||
required
|
||||
autoFocus
|
||||
label={t<string>('builder.leftSidebar.sections.experience.form.name.label')}
|
||||
label={t('builder.leftSidebar.sections.experience.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -133,7 +133,7 @@ const WorkModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
required
|
||||
label={t<string>('builder.common.form.position.label')}
|
||||
label={t('builder.common.form.position.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -148,7 +148,7 @@ const WorkModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.start-date.label')}
|
||||
label={t('builder.common.form.start-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -174,7 +174,7 @@ const WorkModal: React.FC = () => {
|
||||
<DatePicker
|
||||
openTo="year"
|
||||
inputRef={field.ref}
|
||||
label={t<string>('builder.common.form.end-date.label')}
|
||||
label={t('builder.common.form.end-date.label')}
|
||||
value={dayjs(field.value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
@ -182,7 +182,7 @@ const WorkModal: React.FC = () => {
|
||||
<TextField
|
||||
{...params}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || t<string>('builder.common.form.end-date.help-text')}
|
||||
helperText={fieldState.error?.message || t('builder.common.form.end-date.help-text')}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
@ -198,7 +198,7 @@ const WorkModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('builder.common.form.url.label')}
|
||||
label={t('builder.common.form.url.label')}
|
||||
placeholder="https://"
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
@ -216,7 +216,7 @@ const WorkModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
label={t('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
|
||||
@ -80,15 +80,15 @@ const CreateResumeModal: React.FC = () => {
|
||||
<BaseModal
|
||||
isOpen={isOpen}
|
||||
icon={<Add />}
|
||||
heading={t<string>('modals.dashboard.create-resume.heading')}
|
||||
heading={t('modals.dashboard.create-resume.heading')}
|
||||
handleClose={handleClose}
|
||||
footerChildren={
|
||||
<Button type="submit" disabled={isLoading} onClick={handleSubmit(onSubmit)}>
|
||||
{t<string>('modals.dashboard.create-resume.actions.create-resume')}
|
||||
{t('modals.dashboard.create-resume.actions.create-resume')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<p>{t<string>('modals.dashboard.create-resume.body')}</p>
|
||||
<p>{t('modals.dashboard.create-resume.body')}</p>
|
||||
|
||||
<form className="grid gap-4">
|
||||
<Controller
|
||||
@ -97,7 +97,7 @@ const CreateResumeModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
autoFocus
|
||||
label={t<string>('modals.dashboard.create-resume.form.name.label')}
|
||||
label={t('modals.dashboard.create-resume.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -110,7 +110,7 @@ const CreateResumeModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('modals.dashboard.create-resume.form.slug.label')}
|
||||
label={t('modals.dashboard.create-resume.form.slug.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -120,7 +120,7 @@ const CreateResumeModal: React.FC = () => {
|
||||
|
||||
<FormGroup>
|
||||
<FormControlLabel
|
||||
label={t<string>('modals.dashboard.create-resume.form.public.label')}
|
||||
label={t('modals.dashboard.create-resume.form.public.label')}
|
||||
control={
|
||||
<Controller
|
||||
name="isPublic"
|
||||
|
||||
@ -63,7 +63,7 @@ const ImportExternalModal: React.FC = () => {
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (file.size > FILE_UPLOAD_MAX_SIZE) {
|
||||
toast.error(t<string>('common.toast.error.upload-file-size'));
|
||||
toast.error(t('common.toast.error.upload-file-size'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -78,13 +78,13 @@ const ImportExternalModal: React.FC = () => {
|
||||
<BaseModal
|
||||
isOpen={isOpen}
|
||||
icon={<ImportExport />}
|
||||
heading={t<string>('modals.dashboard.import-external.heading')}
|
||||
heading={t('modals.dashboard.import-external.heading')}
|
||||
handleClose={handleClose}
|
||||
>
|
||||
<div className="grid gap-5">
|
||||
<h2 className="inline-flex items-center gap-2 text-lg font-medium">
|
||||
<LinkedIn />
|
||||
{t<string>('modals.dashboard.import-external.linkedin.heading')}
|
||||
{t('modals.dashboard.import-external.linkedin.heading')}
|
||||
</h2>
|
||||
|
||||
<p className="mb-2">
|
||||
@ -110,7 +110,7 @@ const ImportExternalModal: React.FC = () => {
|
||||
startIcon={<UploadFile />}
|
||||
onClick={() => handleClick('linkedin')}
|
||||
>
|
||||
{t<string>('modals.dashboard.import-external.linkedin.actions.upload-archive')}
|
||||
{t('modals.dashboard.import-external.linkedin.actions.upload-archive')}
|
||||
</Button>
|
||||
|
||||
<input
|
||||
@ -128,7 +128,7 @@ const ImportExternalModal: React.FC = () => {
|
||||
<div className="grid gap-5">
|
||||
<h2 className="inline-flex items-center gap-2 text-lg font-medium">
|
||||
<Code />
|
||||
{t<string>('modals.dashboard.import-external.json-resume.heading')}
|
||||
{t('modals.dashboard.import-external.json-resume.heading')}
|
||||
</h2>
|
||||
|
||||
<p className="mb-2">
|
||||
@ -154,7 +154,7 @@ const ImportExternalModal: React.FC = () => {
|
||||
startIcon={<UploadFile />}
|
||||
onClick={() => handleClick('json-resume')}
|
||||
>
|
||||
{t<string>('modals.dashboard.import-external.json-resume.actions.upload-json')}
|
||||
{t('modals.dashboard.import-external.json-resume.actions.upload-json')}
|
||||
</Button>
|
||||
|
||||
<input
|
||||
@ -172,10 +172,10 @@ const ImportExternalModal: React.FC = () => {
|
||||
<div className="grid gap-5">
|
||||
<h2 className="inline-flex items-center gap-2 text-lg font-medium">
|
||||
<TrackChanges />
|
||||
{t<string>('modals.dashboard.import-external.reactive-resume.heading')}
|
||||
{t('modals.dashboard.import-external.reactive-resume.heading')}
|
||||
</h2>
|
||||
|
||||
<p className="mb-2">{t<string>('modals.dashboard.import-external.reactive-resume.body')}</p>
|
||||
<p className="mb-2">{t('modals.dashboard.import-external.reactive-resume.body')}</p>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<Button
|
||||
@ -184,7 +184,7 @@ const ImportExternalModal: React.FC = () => {
|
||||
startIcon={<UploadFile />}
|
||||
onClick={() => handleClick('reactive-resume')}
|
||||
>
|
||||
{t<string>('modals.dashboard.import-external.reactive-resume.actions.upload-json')}
|
||||
{t('modals.dashboard.import-external.reactive-resume.actions.upload-json')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
@ -193,7 +193,7 @@ const ImportExternalModal: React.FC = () => {
|
||||
startIcon={<UploadFile />}
|
||||
onClick={() => handleClick('reactive-resume-v2')}
|
||||
>
|
||||
{t<string>('modals.dashboard.import-external.reactive-resume.actions.upload-json-v2')}
|
||||
{t('modals.dashboard.import-external.reactive-resume.actions.upload-json-v2')}
|
||||
</Button>
|
||||
|
||||
<input
|
||||
|
||||
@ -92,11 +92,11 @@ const RenameResumeModal: React.FC = () => {
|
||||
<BaseModal
|
||||
icon={<DriveFileRenameOutline />}
|
||||
isOpen={isOpen}
|
||||
heading={t<string>('modals.dashboard.rename-resume.heading')}
|
||||
heading={t('modals.dashboard.rename-resume.heading')}
|
||||
handleClose={handleClose}
|
||||
footerChildren={
|
||||
<Button type="submit" disabled={isLoading} onClick={handleSubmit(onSubmit)}>
|
||||
{t<string>('modals.dashboard.rename-resume.actions.rename-resume')}
|
||||
{t('modals.dashboard.rename-resume.actions.rename-resume')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
@ -107,7 +107,7 @@ const RenameResumeModal: React.FC = () => {
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
autoFocus
|
||||
label={t<string>('modals.dashboard.rename-resume.form.name.label')}
|
||||
label={t('modals.dashboard.rename-resume.form.name.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
@ -120,7 +120,7 @@ const RenameResumeModal: React.FC = () => {
|
||||
control={control}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
label={t<string>('modals.dashboard.rename-resume.form.slug.label')}
|
||||
label={t('modals.dashboard.rename-resume.form.slug.label')}
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
{...field}
|
||||
|
||||
Reference in New Issue
Block a user