diff --git a/client/components/build/Center/ArtboardController.tsx b/client/components/build/Center/ArtboardController.tsx index 66b5283a..57322739 100644 --- a/client/components/build/Center/ArtboardController.tsx +++ b/client/components/build/Center/ArtboardController.tsx @@ -14,11 +14,11 @@ import { import { ButtonBase, Divider, Tooltip, useMediaQuery, useTheme } from '@mui/material'; import clsx from 'clsx'; import dayjs from 'dayjs'; -import { get } from 'lodash'; +import get from 'lodash/get'; import { useTranslation } from 'next-i18next'; import toast from 'react-hot-toast'; import { useMutation } from 'react-query'; -import { ReactZoomPanPinchRef } from 'react-zoom-pan-pinch'; +import { ReactZoomPanPinchHandlers } from 'react-zoom-pan-pinch'; import { ActionCreators } from 'redux-undo'; import { ServerError } from '@/services/axios'; @@ -29,7 +29,7 @@ import getResumeUrl from '@/utils/getResumeUrl'; import styles from './ArtboardController.module.scss'; -const ArtboardController: React.FC = ({ zoomIn, zoomOut, centerView }) => { +const ArtboardController: React.FC = ({ zoomIn, zoomOut, centerView }) => { const { t } = useTranslation(); const theme = useTheme(); diff --git a/client/components/build/RightSidebar/RightSidebar.tsx b/client/components/build/RightSidebar/RightSidebar.tsx index 6b6a9b94..5989c47a 100644 --- a/client/components/build/RightSidebar/RightSidebar.tsx +++ b/client/components/build/RightSidebar/RightSidebar.tsx @@ -1,5 +1,5 @@ import { Divider, IconButton, SwipeableDrawer, Tooltip, useMediaQuery, useTheme } from '@mui/material'; -import { capitalize } from 'lodash'; +import capitalize from 'lodash/capitalize'; import { useTranslation } from 'next-i18next'; import Avatar from '@/components/shared/Avatar'; diff --git a/client/components/shared/Markdown.tsx b/client/components/shared/Markdown.tsx index 3d4d9bb6..2c724bc0 100644 --- a/client/components/shared/Markdown.tsx +++ b/client/components/shared/Markdown.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { isEmpty } from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import ReactMarkdown from 'react-markdown'; import rehypeKatex from 'rehype-katex'; import remarkGfm from 'remark-gfm'; diff --git a/client/components/shared/ResumeInput.tsx b/client/components/shared/ResumeInput.tsx index 7ce1ec1a..24400c2a 100644 --- a/client/components/shared/ResumeInput.tsx +++ b/client/components/shared/ResumeInput.tsx @@ -1,7 +1,6 @@ import { TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import dayjs from 'dayjs'; -import { isEmpty } from 'lodash'; import get from 'lodash/get'; import { useEffect, useState } from 'react'; @@ -22,7 +21,6 @@ const ResumeInput: React.FC = ({ type = 'text', label, path, className, m const dispatch = useAppDispatch(); const stateValue = useAppSelector((state) => get(state.resume.present, path, '')); - const dateFormat = useAppSelector((state) => state.resume.present.metadata.date.format); useEffect(() => { setValue(stateValue); @@ -57,15 +55,14 @@ const ResumeInput: React.FC = ({ type = 'text', label, path, className, m if (type === 'date') { return ( } - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && onChangeValue(''); + slots={{ + textField: (params) => , + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && onChangeValue(dayjs(date).format('YYYY-MM-DD')); }} /> diff --git a/client/modals/auth/LoginModal.tsx b/client/modals/auth/LoginModal.tsx index bdd90d79..562567c4 100644 --- a/client/modals/auth/LoginModal.tsx +++ b/client/modals/auth/LoginModal.tsx @@ -4,7 +4,7 @@ import { Login, Visibility, VisibilityOff } from '@mui/icons-material'; import { Button, IconButton, InputAdornment, TextField } from '@mui/material'; import { CredentialResponse, GoogleLogin } from '@react-oauth/google'; import Joi from 'joi'; -import { isEmpty } from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import { Trans, useTranslation } from 'next-i18next'; import { useMemo, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; diff --git a/client/modals/auth/RegisterModal.tsx b/client/modals/auth/RegisterModal.tsx index 549161f1..8008f6b5 100644 --- a/client/modals/auth/RegisterModal.tsx +++ b/client/modals/auth/RegisterModal.tsx @@ -4,7 +4,7 @@ import { HowToReg } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; import { CredentialResponse, GoogleLogin } from '@react-oauth/google'; import Joi from 'joi'; -import { isEmpty } from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import { Trans, useTranslation } from 'next-i18next'; import { Controller, useForm } from 'react-hook-form'; import toast from 'react-hot-toast'; diff --git a/client/modals/builder/sections/AwardModal.tsx b/client/modals/builder/sections/AwardModal.tsx index a7f206a9..346bd3b2 100644 --- a/client/modals/builder/sections/AwardModal.tsx +++ b/client/modals/builder/sections/AwardModal.tsx @@ -1,7 +1,7 @@ import { joiResolver } from '@hookform/resolvers/joi'; import { Add, DriveFileRenameOutline } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { Award, SectionPath } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -128,21 +128,23 @@ const AwardModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> diff --git a/client/modals/builder/sections/CertificateModal.tsx b/client/modals/builder/sections/CertificateModal.tsx index 7de8e355..eb876b74 100644 --- a/client/modals/builder/sections/CertificateModal.tsx +++ b/client/modals/builder/sections/CertificateModal.tsx @@ -1,7 +1,7 @@ import { joiResolver } from '@hookform/resolvers/joi'; import { Add, DriveFileRenameOutline } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { Certificate, SectionPath } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -128,21 +128,23 @@ const CertificateModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> diff --git a/client/modals/builder/sections/CustomModal.tsx b/client/modals/builder/sections/CustomModal.tsx index 8e298302..dbbc45c3 100644 --- a/client/modals/builder/sections/CustomModal.tsx +++ b/client/modals/builder/sections/CustomModal.tsx @@ -1,7 +1,7 @@ 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'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { Custom } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -145,21 +145,23 @@ const CustomModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.start-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> @@ -169,21 +171,23 @@ const CustomModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.end-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + ('builder.common.form.end-date.help-text')} + /> + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> diff --git a/client/modals/builder/sections/EducationModal.tsx b/client/modals/builder/sections/EducationModal.tsx index e67ed84b..e2c020ce 100644 --- a/client/modals/builder/sections/EducationModal.tsx +++ b/client/modals/builder/sections/EducationModal.tsx @@ -1,7 +1,7 @@ import { joiResolver } from '@hookform/resolvers/joi'; import { Add, DriveFileRenameOutline } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { Education, SectionPath } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -167,21 +167,23 @@ const EducationModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.start-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> @@ -191,21 +193,23 @@ const EducationModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.end-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + ('builder.common.form.end-date.help-text')} + /> + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - ('builder.common.form.end-date.help-text')} - /> - )} /> )} /> diff --git a/client/modals/builder/sections/ProjectModal.tsx b/client/modals/builder/sections/ProjectModal.tsx index a1f88707..93b82a4e 100644 --- a/client/modals/builder/sections/ProjectModal.tsx +++ b/client/modals/builder/sections/ProjectModal.tsx @@ -1,7 +1,7 @@ import { joiResolver } from '@hookform/resolvers/joi'; import { Add, DriveFileRenameOutline } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { Project, SectionPath } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -137,21 +137,23 @@ const ProjectModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.start-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> @@ -161,21 +163,23 @@ const ProjectModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.end-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + ('builder.common.form.end-date.help-text')} + /> + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> diff --git a/client/modals/builder/sections/PublicationModal.tsx b/client/modals/builder/sections/PublicationModal.tsx index 77e74632..2d0a1522 100644 --- a/client/modals/builder/sections/PublicationModal.tsx +++ b/client/modals/builder/sections/PublicationModal.tsx @@ -1,7 +1,7 @@ import { joiResolver } from '@hookform/resolvers/joi'; import { Add, DriveFileRenameOutline } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { Publication, SectionPath } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -128,21 +128,23 @@ const PublicationModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> diff --git a/client/modals/builder/sections/VolunteerModal.tsx b/client/modals/builder/sections/VolunteerModal.tsx index 42244d47..12d021ff 100644 --- a/client/modals/builder/sections/VolunteerModal.tsx +++ b/client/modals/builder/sections/VolunteerModal.tsx @@ -1,7 +1,7 @@ import { joiResolver } from '@hookform/resolvers/joi'; import { Add, DriveFileRenameOutline } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { SectionPath, Volunteer } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -134,21 +134,23 @@ const VolunteerModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.start-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> @@ -158,21 +160,23 @@ const VolunteerModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.end-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + ('builder.common.form.end-date.help-text')} + /> + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> diff --git a/client/modals/builder/sections/WorkModal.tsx b/client/modals/builder/sections/WorkModal.tsx index 7c7980ae..952f5f84 100644 --- a/client/modals/builder/sections/WorkModal.tsx +++ b/client/modals/builder/sections/WorkModal.tsx @@ -1,7 +1,7 @@ import { joiResolver } from '@hookform/resolvers/joi'; import { Add, DriveFileRenameOutline } from '@mui/icons-material'; import { Button, TextField } from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { WorkExperience } from '@reactive-resume/schema'; import dayjs from 'dayjs'; import Joi from 'joi'; @@ -141,21 +141,23 @@ const WorkModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.start-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - - )} /> )} /> @@ -165,21 +167,23 @@ const WorkModal: React.FC = () => { control={control} render={({ field, fieldState }) => ( ('builder.common.form.end-date.label')} + value={dayjs(field.value)} views={['year', 'month', 'day']} - onChange={(date: Date | null, keyboardInputValue: string | undefined) => { - isEmpty(keyboardInputValue) && field.onChange(''); + slots={{ + textField: (params) => ( + ('builder.common.form.end-date.help-text')} + /> + ), + }} + onChange={(date: dayjs.Dayjs | null) => { date && dayjs(date).isValid() && field.onChange(dayjs(date).format('YYYY-MM-DD')); }} - renderInput={(params) => ( - ('builder.common.form.end-date.help-text')} - /> - )} /> )} /> diff --git a/client/pages/_app.tsx b/client/pages/_app.tsx index 0f79a144..3b109b92 100644 --- a/client/pages/_app.tsx +++ b/client/pages/_app.tsx @@ -1,8 +1,8 @@ import '@/styles/globals.scss'; import env from '@beam-australia/react-env'; -import { LocalizationProvider } from '@mui/x-date-pickers'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { GoogleOAuthProvider } from '@react-oauth/google'; import type { AppProps } from 'next/app'; import Head from 'next/head'; diff --git a/client/templates/sectionMap.tsx b/client/templates/sectionMap.tsx index 4dc49a89..facbd479 100644 --- a/client/templates/sectionMap.tsx +++ b/client/templates/sectionMap.tsx @@ -1,4 +1,4 @@ -import { find } from 'lodash'; +import find from 'lodash/find'; import get from 'lodash/get'; import React from 'react'; import { validate } from 'uuid'; diff --git a/package.json b/package.json index 509254db..6cdf6946 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "reactive-resume", - "version": "3.6.19", + "version": "3.7.0", "private": true, "scripts": { "dev": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version turbo run dev", "build": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version turbo run build", "start": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version turbo run start", - "update-deps": "ncu -x nanoid,class-validator --deep -u && pnpm install", + "update-deps": "ncu -x nanoid --deep -u && pnpm install", "generate-env": "ts-node ./scripts/generate-env.ts", "format": "prettier --write .", "lint": "turbo run lint" diff --git a/server/src/fonts/fonts.service.ts b/server/src/fonts/fonts.service.ts index d73e9273..743ab0b6 100644 --- a/server/src/fonts/fonts.service.ts +++ b/server/src/fonts/fonts.service.ts @@ -2,7 +2,7 @@ import { HttpService } from '@nestjs/axios'; import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Font } from '@reactive-resume/schema'; -import { get } from 'lodash'; +import get from 'lodash/get'; import { firstValueFrom } from 'rxjs'; import cachedResponse from './assets/cachedResponse.json'; diff --git a/server/src/integrations/integrations.service.ts b/server/src/integrations/integrations.service.ts index c0526ea5..1e6a232a 100644 --- a/server/src/integrations/integrations.service.ts +++ b/server/src/integrations/integrations.service.ts @@ -16,7 +16,10 @@ import { import csv from 'csvtojson'; import dayjs from 'dayjs'; import { readFile, unlink } from 'fs/promises'; -import { cloneDeep, get, isEmpty, merge } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; +import get from 'lodash/get'; +import isEmpty from 'lodash/isEmpty'; +import merge from 'lodash/merge'; import StreamZip from 'node-stream-zip'; import { DeepPartial } from 'typeorm'; import { v4 as uuidv4 } from 'uuid'; diff --git a/server/src/resume/resume.service.ts b/server/src/resume/resume.service.ts index 9f04c9aa..5525d9a7 100644 --- a/server/src/resume/resume.service.ts +++ b/server/src/resume/resume.service.ts @@ -4,7 +4,10 @@ import { ConfigService } from '@nestjs/config'; import { InjectRepository } from '@nestjs/typeorm'; import { Resume as ResumeSchema } from '@reactive-resume/schema'; import fs from 'fs/promises'; -import { isEmpty, pick, sample, set } from 'lodash'; +import isEmpty from 'lodash/isEmpty'; +import pick from 'lodash/pick'; +import sample from 'lodash/sample'; +import set from 'lodash/set'; import { nanoid } from 'nanoid'; import { extname } from 'path'; import { Repository } from 'typeorm';