mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-10 04:22:27 +10:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 48a0f90597 | |||
| 05d3f1f06f | |||
| 4d43f6a642 | |||
| f7363ccdd7 | |||
| 07c91e9ac2 | |||
| cbe08f1d2c | |||
| c2617a8277 | |||
| fe72d2de41 | |||
| 23667e218f | |||
| 977fa72dde | |||
| 5197f954c0 | |||
| 58341e4cd2 | |||
| 1559703567 | |||
| 0a1fd50d07 | |||
| 1c19062c63 | |||
| 25cf594eb9 | |||
| 1c3beee6cd | |||
| 95c3d4c315 | |||
| 85df339e56 | |||
| d61ad44ebc | |||
| ccb1eff749 | |||
| bfb48e3aa7 | |||
| e2e08ad390 | |||
| f0dda06af3 | |||
| 4c4e77e21d | |||
| f364ae8929 | |||
| b52f292d89 | |||
| 8cac7f907c | |||
| a18a60679f | |||
| 5cc6a81b8c | |||
| 6ff212b698 | |||
| 56bcec5196 | |||
| 12019f90e9 | |||
| 7e6e69ed49 | |||
| a09a945e17 | |||
| df714dc8de | |||
| 28b63ef0c7 | |||
| 1b594dac61 | |||
| dd34a30ee0 | |||
| 0af398ceed | |||
| 04abd2cacc |
4
.github/workflows/docker-build-push.yml
vendored
4
.github/workflows/docker-build-push.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build and Push Client Image
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
uses: docker/build-push-action@v3.1.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
@ -68,7 +68,7 @@ jobs:
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build and Push Server Image
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
uses: docker/build-push-action@v3.1.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
2
.npmrc
Normal file
2
.npmrc
Normal file
@ -0,0 +1,2 @@
|
||||
auto-install-peers=true
|
||||
strict-peer-dependencies=false
|
||||
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -21,5 +21,10 @@
|
||||
"i18n-ally.namespace": true,
|
||||
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
|
||||
"i18n-ally.sortKeys": true,
|
||||
"scss.validate": false
|
||||
"scss.validate": false,
|
||||
"conventionalCommits.scopes": [
|
||||
"client",
|
||||
"server",
|
||||
"docker"
|
||||
]
|
||||
}
|
||||
35
CHANGELOG.md
35
CHANGELOG.md
@ -2,6 +2,41 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [3.5.1](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.5.0...v3.5.1) (2022-07-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **client:** :sparkles: ask for confirmation when resetting a resume ([4d43f6a](https://github.com/AmruthPillai/Reactive-Resume/commit/4d43f6a6427198e62e9fcb995f1a28c0ee4de71e))
|
||||
* **docker:** :zap: remove ports from postgres docker instance ([07c91e9](https://github.com/AmruthPillai/Reactive-Resume/commit/07c91e9ac21e8ef120d08ab92363d8e48a55aaba))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **server:** :zap: don't initialize sendgrid if the apikey is empty ([05d3f1f](https://github.com/AmruthPillai/Reactive-Resume/commit/05d3f1f06fbffd899269a5c4dea3c52cf408125f))
|
||||
|
||||
## [3.5.0](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.8...v3.5.0) (2022-07-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **client:** :bug: attempt to fix the one-off date issue ([5197f95](https://github.com/AmruthPillai/Reactive-Resume/commit/5197f954c0baed3daf1c7e2c79b607354ef42024))
|
||||
* **client:** :bug: fix mui rendering of utc dates ([977fa72](https://github.com/AmruthPillai/Reactive-Resume/commit/977fa72ddeeeebf7463d43a820e85f783489a4dc))
|
||||
|
||||
### [3.4.8](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.7...v3.4.8) (2022-07-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **google:** add toast to display error message from google ([25cf594](https://github.com/AmruthPillai/Reactive-Resume/commit/25cf594eb948e1c2d6157028ee1fff2799df5f92))
|
||||
|
||||
### [3.4.7](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.6...v3.4.7) (2022-06-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **mui:** update mui datepickers to newer package ([bfb48e3](https://github.com/AmruthPillai/Reactive-Resume/commit/bfb48e3aa7e0575922841522edc1d38544d1884f))
|
||||
|
||||
### [3.4.6](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.5...v3.4.6) (2022-06-19)
|
||||
|
||||
## [3.6.0](https://github.com/dvd741-a/Reactive-Resume/compare/v3.3.4...v3.6.0) (2022-06-05)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.2' apply false
|
||||
id 'com.android.library' version '7.1.2' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
||||
@ -15,7 +15,7 @@ import dayjs from 'dayjs';
|
||||
import get from 'lodash/get';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useMemo } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
|
||||
import Heading from '@/components/shared/Heading';
|
||||
@ -36,6 +36,8 @@ const Settings = () => {
|
||||
|
||||
const { locale, ...router } = useRouter();
|
||||
|
||||
const [confirmReset, setConfirmReset] = useState(false);
|
||||
|
||||
const resume = useAppSelector((state) => state.resume);
|
||||
const theme = useAppSelector((state) => state.build.theme);
|
||||
const pages = useAppSelector((state) => state.resume.metadata.layout);
|
||||
@ -48,7 +50,7 @@ const Settings = () => {
|
||||
const dateConfig: DateConfig = useMemo(() => get(resume, 'metadata.date'), [resume]);
|
||||
|
||||
const isDarkMode = useMemo(() => theme === 'dark', [theme]);
|
||||
const exampleString = useMemo(() => `Eg. ${dayjs().format(dateConfig.format)}`, [dateConfig.format]);
|
||||
const exampleString = useMemo(() => `Eg. ${dayjs().utc().format(dateConfig.format)}`, [dateConfig.format]);
|
||||
const themeString = useMemo(() => (isDarkMode ? 'Matte Black Everything' : 'As bright as your future'), [isDarkMode]);
|
||||
|
||||
const { mutateAsync: loadSampleDataMutation } = useMutation<Resume, ServerError, LoadSampleDataParams>(
|
||||
@ -78,9 +80,14 @@ const Settings = () => {
|
||||
};
|
||||
|
||||
const handleResetResume = async () => {
|
||||
await resetResumeMutation({ id });
|
||||
if (!confirmReset) {
|
||||
return setConfirmReset(true);
|
||||
}
|
||||
|
||||
queryClient.invalidateQueries(`resume/${username}/${slug}`);
|
||||
await resetResumeMutation({ id });
|
||||
await queryClient.invalidateQueries(`resume/${username}/${slug}`);
|
||||
|
||||
setConfirmReset(false);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -202,7 +209,11 @@ const Settings = () => {
|
||||
<DeleteForever />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.resume.reset.primary')}
|
||||
primary={
|
||||
confirmReset
|
||||
? 'Are you sure?'
|
||||
: t<string>('builder.rightSidebar.sections.settings.resume.reset.primary')
|
||||
}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.resume.reset.secondary')}
|
||||
/>
|
||||
</ListItemButton>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { DatePicker } from '@mui/lab';
|
||||
import { TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import dayjs from 'dayjs';
|
||||
import { isEmpty } from 'lodash';
|
||||
import get from 'lodash/get';
|
||||
@ -63,7 +63,7 @@ const ResumeInput: React.FC<Props> = ({ type = 'text', label, path, className, m
|
||||
renderInput={(params) => <TextField {...params} error={false} className={className} />}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && onChangeValue('');
|
||||
date && dayjs(date).isValid() && onChangeValue(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && onChangeValue(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -87,16 +87,24 @@ const LoginModal: React.FC = () => {
|
||||
|
||||
const handleLoginWithGoogle = async () => {
|
||||
google.accounts.id.initialize({
|
||||
auto_select: true,
|
||||
itp_support: true,
|
||||
client_id: env('GOOGLE_CLIENT_ID'),
|
||||
callback: async (response: any) => {
|
||||
await loginWithGoogleMutation({ credential: response.credential });
|
||||
|
||||
handleClose();
|
||||
},
|
||||
auto_select: false,
|
||||
});
|
||||
|
||||
google.accounts.id.prompt();
|
||||
google.accounts.id.prompt((notification: any) => {
|
||||
if (notification.isNotDisplayed() || notification.isSkippedMoment()) {
|
||||
const reason = notification.getNotDisplayedReason() || notification.getSkippedReason();
|
||||
|
||||
toast.error(`Google returned an error while trying to sign in: ${reason}.`);
|
||||
toast("Please try logging in using email/password, or use another browser that supports Google's One Tap API.");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const PasswordVisibility = (): React.ReactElement => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { Award, SectionPath } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -134,7 +134,7 @@ const AwardModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { Certificate, SectionPath } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -134,7 +134,7 @@ const CertificateModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, Slider, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { Custom } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -150,7 +150,7 @@ const CustomModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
@ -174,7 +174,7 @@ const CustomModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { Education, SectionPath } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -173,7 +173,7 @@ const EducationModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
@ -197,7 +197,7 @@ const EducationModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { Project, SectionPath } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -143,7 +143,7 @@ const ProjectModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
@ -167,7 +167,7 @@ const ProjectModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { Publication, SectionPath } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -134,7 +134,7 @@ const PublicationModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { SectionPath, Volunteer } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -140,7 +140,7 @@ const VolunteerModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
@ -164,7 +164,7 @@ const VolunteerModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import DatePicker from '@mui/lab/DatePicker';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { SectionPath, WorkExperience } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
@ -140,7 +140,7 @@ const WorkModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
@ -164,7 +164,7 @@ const WorkModal: React.FC = () => {
|
||||
views={['year', 'month', 'day']}
|
||||
onChange={(date: Date | null, keyboardInputValue: string | undefined) => {
|
||||
isEmpty(keyboardInputValue) && field.onChange('');
|
||||
date && dayjs(date).isValid() && field.onChange(date.toISOString());
|
||||
date && dayjs(date).utc().isValid() && field.onChange(dayjs(date).utc().toISOString());
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
|
||||
@ -13,70 +13,70 @@
|
||||
"@emotion/css": "^11.9.0",
|
||||
"@emotion/react": "^11.9.3",
|
||||
"@emotion/styled": "^11.9.3",
|
||||
"@hookform/resolvers": "2.9.1",
|
||||
"@hookform/resolvers": "2.9.7",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@mui/icons-material": "^5.8.4",
|
||||
"@mui/lab": "^5.0.0-alpha.86",
|
||||
"@mui/material": "^5.8.4",
|
||||
"@mui/system": "^5.8.4",
|
||||
"@mui/x-date-pickers": "5.0.0-alpha.6",
|
||||
"@next/env": "^12.1.6",
|
||||
"@reduxjs/toolkit": "^1.8.2",
|
||||
"@mui/lab": "^5.0.0-alpha.92",
|
||||
"@mui/material": "^5.9.2",
|
||||
"@mui/system": "^5.9.2",
|
||||
"@mui/x-date-pickers": "5.0.0-beta.3",
|
||||
"@next/env": "^12.2.3",
|
||||
"@reduxjs/toolkit": "^1.8.3",
|
||||
"axios": "^0.27.2",
|
||||
"clsx": "^1.1.1",
|
||||
"dayjs": "^1.11.3",
|
||||
"clsx": "^1.2.1",
|
||||
"dayjs": "^1.11.4",
|
||||
"downloadjs": "^1.4.7",
|
||||
"joi": "^17.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"md5-hex": "^4.0.0",
|
||||
"monaco-editor": "^0.33.0",
|
||||
"nanoid": "^3.3.4",
|
||||
"next": "12.1.6",
|
||||
"next-i18next": "^11.0.0",
|
||||
"next": "12.2.3",
|
||||
"next-i18next": "^11.3.0",
|
||||
"react": "18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-colorful": "^5.5.1",
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.32.2",
|
||||
"react-hot-toast": "2.2.0",
|
||||
"react-hotkeys-hook": "^3.4.6",
|
||||
"react-hook-form": "^7.34.0",
|
||||
"react-hot-toast": "2.3.0",
|
||||
"react-hotkeys-hook": "^3.4.7",
|
||||
"react-icons": "^4.4.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-query": "^3.39.1",
|
||||
"react-query": "^3.39.2",
|
||||
"react-redux": "^8.0.2",
|
||||
"react-zoom-pan-pinch": "^2.1.3",
|
||||
"redux": "^4.2.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-saga": "^1.1.3",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"sharp": "^0.30.6",
|
||||
"sharp": "^0.30.7",
|
||||
"uuid": "^8.3.2",
|
||||
"webfontloader": "^1.6.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.5",
|
||||
"@babel/core": "^7.18.9",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"@tailwindcss/typography": "^0.5.4",
|
||||
"@types/downloadjs": "^1.4.3",
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@types/node": "18.0.0",
|
||||
"@types/react": "18.0.14",
|
||||
"@types/node": "18.6.2",
|
||||
"@types/react": "18.0.15",
|
||||
"@types/react-beautiful-dnd": "^13.1.2",
|
||||
"@types/react-redux": "^7.1.24",
|
||||
"@types/tailwindcss": "^3.0.10",
|
||||
"@types/tailwindcss": "^3.0.11",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/webfontloader": "^1.6.34",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"autoprefixer": "^10.4.8",
|
||||
"csstype": "^3.1.0",
|
||||
"eslint": "^8.18.0",
|
||||
"eslint-config-next": "12.1.6",
|
||||
"next-sitemap": "^3.1.1",
|
||||
"eslint": "^8.20.0",
|
||||
"eslint-config-next": "12.2.3",
|
||||
"next-sitemap": "^3.1.15",
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^2.7.1",
|
||||
"sass": "^1.52.3",
|
||||
"tailwindcss": "^3.1.3",
|
||||
"sass": "^1.54.0",
|
||||
"tailwindcss": "^3.1.7",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import '@/styles/globals.scss';
|
||||
|
||||
import DayjsAdapter from '@date-io/dayjs';
|
||||
import { LocalizationProvider } from '@mui/lab';
|
||||
import { LocalizationProvider } from '@mui/x-date-pickers';
|
||||
import type { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import Script from 'next/script';
|
||||
@ -54,7 +54,7 @@ const App: React.FC<AppProps> = ({ Component, pageProps }) => {
|
||||
</LocalizationProvider>
|
||||
</ReduxProvider>
|
||||
|
||||
<Script src="https://accounts.google.com/gsi/client" />
|
||||
<Script src="https://accounts.google.com/gsi/client" async defer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
361
client/public/locales/he/builder.json
Normal file
361
client/public/locales/he/builder.json
Normal file
@ -0,0 +1,361 @@
|
||||
{
|
||||
"common": {
|
||||
"actions": {
|
||||
"add": "הוסף חדש{{token}}",
|
||||
"delete": "מחק{{token}}",
|
||||
"edit": "ערוך{{token}}"
|
||||
},
|
||||
"columns": {
|
||||
"heading": "טורים",
|
||||
"tooltip": "שנה את מספר הטורים"
|
||||
},
|
||||
"form": {
|
||||
"date": {
|
||||
"label": "תאריך"
|
||||
},
|
||||
"description": {
|
||||
"label": "תיאור"
|
||||
},
|
||||
"email": {
|
||||
"label": "כתובת דוא\"ל"
|
||||
},
|
||||
"end-date": {
|
||||
"help-text": "השאר שדה זה ריק, אם אתה עדיין נמצא שם",
|
||||
"label": "תאריך סיום"
|
||||
},
|
||||
"keywords": {
|
||||
"label": "מילות מפתח"
|
||||
},
|
||||
"level": {
|
||||
"label": "רמה"
|
||||
},
|
||||
"levelNum": {
|
||||
"label": "רמה (מספר)"
|
||||
},
|
||||
"name": {
|
||||
"label": "שם"
|
||||
},
|
||||
"phone": {
|
||||
"label": "מספר טלפון"
|
||||
},
|
||||
"position": {
|
||||
"label": "תפקיד בעבודה"
|
||||
},
|
||||
"start-date": {
|
||||
"label": "תאריך התחלה"
|
||||
},
|
||||
"subtitle": {
|
||||
"label": "תת כותרת"
|
||||
},
|
||||
"summary": {
|
||||
"label": "סיכום"
|
||||
},
|
||||
"title": {
|
||||
"label": "כותרת"
|
||||
},
|
||||
"url": {
|
||||
"label": "אתר"
|
||||
}
|
||||
},
|
||||
"glossary": {
|
||||
"page": "דף"
|
||||
},
|
||||
"list": {
|
||||
"actions": {
|
||||
"delete": "מחיקה",
|
||||
"duplicate": "שכפול",
|
||||
"edit": "עריכה"
|
||||
},
|
||||
"empty-text": "הרשימה ריקה!"
|
||||
},
|
||||
"tooltip": {
|
||||
"delete-item": "האם אתה בטוח שברצונך להסיר פריט זה? זה בלתי הפיך.",
|
||||
"delete-section": "מחיקת קטע",
|
||||
"rename-section": "שנה את שם הקטע",
|
||||
"toggle-visibility": "שנה מצב נראות"
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"tooltip": {
|
||||
"center-artboard": "משטח יצירה מרכזי",
|
||||
"copy-link": "העתק קישור לקורות חיים",
|
||||
"export-pdf": "ייצא PDF",
|
||||
"toggle-orientation": "כיוון דף הבית",
|
||||
"toggle-page-break-line": "החלף את קו מעבר עמוד",
|
||||
"toggle-sidebars": "החלף את סרגלי הצד",
|
||||
"zoom-in": "הגדל",
|
||||
"zoom-out": "הקטן"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"menu": {
|
||||
"delete": "מחיקה",
|
||||
"duplicate": "שכפל",
|
||||
"rename": "שנה שם",
|
||||
"share-link": "שתף קישור",
|
||||
"tooltips": {
|
||||
"delete": "האם אתה בטוח שברצונך להסיר תכונה זו? זה בלתי הפיך.",
|
||||
"share-link": "עליך לשנות את החשיפה של קורות החיים שלך לציבור כדי להפוך אותם לגלויים לאחרים."
|
||||
}
|
||||
}
|
||||
},
|
||||
"leftSidebar": {
|
||||
"sections": {
|
||||
"awards": {
|
||||
"form": {
|
||||
"awarder": {
|
||||
"label": "מעניק"
|
||||
}
|
||||
}
|
||||
},
|
||||
"basics": {
|
||||
"actions": {
|
||||
"photo-filters": "מסנן תמונות"
|
||||
},
|
||||
"heading": "בסיסי",
|
||||
"headline": {
|
||||
"label": "כותרת"
|
||||
},
|
||||
"name": {
|
||||
"label": "שם מלא"
|
||||
},
|
||||
"birthdate": {
|
||||
"label": "תאריך לידה"
|
||||
},
|
||||
"photo-filters": {
|
||||
"effects": {
|
||||
"border": {
|
||||
"label": "גבול"
|
||||
},
|
||||
"grayscale": {
|
||||
"label": "גווני אפור"
|
||||
},
|
||||
"heading": "אפקטים"
|
||||
},
|
||||
"shape": {
|
||||
"heading": "צוּרָה"
|
||||
},
|
||||
"size": {
|
||||
"heading": "גודל (בפיקסלים)"
|
||||
}
|
||||
},
|
||||
"photo-upload": {
|
||||
"tooltip": {
|
||||
"remove": "הסר תמונה",
|
||||
"upload": "העלה תמונה"
|
||||
}
|
||||
}
|
||||
},
|
||||
"certifications": {
|
||||
"form": {
|
||||
"issuer": {
|
||||
"label": "מנפיק"
|
||||
}
|
||||
}
|
||||
},
|
||||
"education": {
|
||||
"form": {
|
||||
"area-study": {
|
||||
"label": "תחום לימוד"
|
||||
},
|
||||
"courses": {
|
||||
"label": "קורסים"
|
||||
},
|
||||
"degree": {
|
||||
"label": "תוֹאַר"
|
||||
},
|
||||
"grade": {
|
||||
"label": "כיתה"
|
||||
},
|
||||
"institution": {
|
||||
"label": "מוֹסָד"
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"address": {
|
||||
"label": "כתובת"
|
||||
},
|
||||
"city": {
|
||||
"label": "עִיר"
|
||||
},
|
||||
"country": {
|
||||
"label": "מדינה"
|
||||
},
|
||||
"heading": "מקום",
|
||||
"postal-code": {
|
||||
"label": "מיקוד"
|
||||
},
|
||||
"region": {
|
||||
"label": "אזור"
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"form": {
|
||||
"network": {
|
||||
"label": "רֶשֶׁת"
|
||||
},
|
||||
"username": {
|
||||
"label": "שם משתמש"
|
||||
}
|
||||
},
|
||||
"heading": "פרופילים",
|
||||
"heading_one": "פּרוֹפִיל"
|
||||
},
|
||||
"publications": {
|
||||
"form": {
|
||||
"publisher": {
|
||||
"label": "מוֹצִיא לָאוֹר"
|
||||
}
|
||||
}
|
||||
},
|
||||
"references": {
|
||||
"form": {
|
||||
"relationship": {
|
||||
"label": "מערכת יחסים"
|
||||
}
|
||||
}
|
||||
},
|
||||
"section": {
|
||||
"heading": "סָעִיף"
|
||||
},
|
||||
"volunteer": {
|
||||
"form": {
|
||||
"organization": {
|
||||
"label": "אִרגוּן"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rightSidebar": {
|
||||
"sections": {
|
||||
"css": {
|
||||
"heading": "CSS מותאם אישית"
|
||||
},
|
||||
"export": {
|
||||
"heading": "יְצוּא",
|
||||
"json": {
|
||||
"primary": "JSON",
|
||||
"secondary": "הורד גירסת JSON של קורות החיים שלך שניתן לייבא חזרה אל קורות חיים ריאקטיביים."
|
||||
},
|
||||
"pdf": {
|
||||
"loading": {
|
||||
"primary": "יצירת PDF",
|
||||
"secondary": "המתן עם יצירת ה-PDF שלך, זה עשוי להימשך עד 15 שניות."
|
||||
},
|
||||
"normal": {
|
||||
"primary": "PDF",
|
||||
"secondary": "הורד קובץ PDF של קורות החיים שלך שתוכל להדפיס ולשלוח לעבודת החלומות שלך. לא ניתן לייבא קובץ זה בחזרה לעריכה נוספת."
|
||||
}
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"heading": "מַעֲרָך",
|
||||
"tooltip": {
|
||||
"reset-layout": "אפס פריסה"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"bugs-features": {
|
||||
"body": "משהו מונע ממך לעשות קורות חיים? או שיש לכם רעיון מדהים להוסיף? העלה בעיה ב-GitHub כדי להתחיל.",
|
||||
"button": "בעיות GitHub",
|
||||
"heading": "באגים? בקשות לתכונה?"
|
||||
},
|
||||
"donate": {
|
||||
"body": "אם אהבתם להשתמש בקורות חיים ריאקטיביים, אנא שקול לתרום ככל שתוכל למען שמירה על האפליקציה ופועלת, ללא פרסומות ובחינם לנצח.",
|
||||
"button": "תקנה לי קפה",
|
||||
"heading": "תרומה לקורות חיים ריאקטיביים"
|
||||
},
|
||||
"github": "קוד מקור",
|
||||
"heading": "קישורים"
|
||||
},
|
||||
"settings": {
|
||||
"global": {
|
||||
"date": {
|
||||
"primary": "תַאֲרִיך",
|
||||
"secondary": "פורמט תאריך לשימוש בכל האפליקציה"
|
||||
},
|
||||
"heading": "גלוֹבָּלִי",
|
||||
"language": {
|
||||
"primary": "שפה",
|
||||
"secondary": "שפת תצוגה לשימוש בכל האפליקציה"
|
||||
},
|
||||
"theme": {
|
||||
"primary": "ערכת נושא"
|
||||
}
|
||||
},
|
||||
"heading": "הגדרות",
|
||||
"page": {
|
||||
"break-line": {
|
||||
"primary": "קו עצירה",
|
||||
"secondary": "הצג קו בכל הדפים כדי לסמן את גובהו של דף A4"
|
||||
},
|
||||
"heading": "דף",
|
||||
"orientation": {
|
||||
"disabled": "אין השפעה כשיש רק עמוד אחד",
|
||||
"primary": "כיוון",
|
||||
"secondary": "האם להציג עמודים אופקית או אנכית"
|
||||
}
|
||||
},
|
||||
"resume": {
|
||||
"heading": "קורות חיים",
|
||||
"reset": {
|
||||
"primary": "אפס הכל",
|
||||
"secondary": "עשית יותר מדי טעויות? לחץ כאן כדי לאפס את כל השינויים ולהתחיל מאפס. היזהר, פעולה זו לא ניתנת לביטול."
|
||||
},
|
||||
"sample": {
|
||||
"primary": "טען נתונים לדוגמה",
|
||||
"secondary": "לא בטוחים מאיפה להתחיל? לחץ כאן כדי לטעון כמה נתונים לדוגמה כדי לראות איך קורות חיים מלאים נראים."
|
||||
}
|
||||
}
|
||||
},
|
||||
"sharing": {
|
||||
"heading": "שיתוף",
|
||||
"short-url": {
|
||||
"label": "העדף כתובת URL קצרה"
|
||||
},
|
||||
"visibility": {
|
||||
"subtitle": "אפשר לכל מי שיש לו קישור לראות את קורות החיים שלך",
|
||||
"title": "גלוי לכול"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"heading": "תבניות"
|
||||
},
|
||||
"theme": {
|
||||
"form": {
|
||||
"background": {
|
||||
"label": "רקע"
|
||||
},
|
||||
"primary": {
|
||||
"label": "ראשי"
|
||||
},
|
||||
"text": {
|
||||
"label": "טקסט"
|
||||
}
|
||||
},
|
||||
"heading": "ערכת נושא"
|
||||
},
|
||||
"typography": {
|
||||
"form": {
|
||||
"font-family": {
|
||||
"label": "משפחת גופן"
|
||||
},
|
||||
"font-size": {
|
||||
"label": "גודל גופן"
|
||||
}
|
||||
},
|
||||
"heading": "טיפוגרפיה",
|
||||
"widgets": {
|
||||
"body": {
|
||||
"label": "גוף"
|
||||
},
|
||||
"headings": {
|
||||
"label": "כותרת"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
client/public/locales/he/dashboard.json
Normal file
25
client/public/locales/he/dashboard.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"create-resume": {
|
||||
"subtitle": "להתחיל מאפס",
|
||||
"title": "צור קורות חיים חדשים"
|
||||
},
|
||||
"import-external": {
|
||||
"subtitle": "לינקדאין, קורות חיים של JSON, קורות חיים ריאקטיביים",
|
||||
"title": "ייבוא ממקורות חיצוניים"
|
||||
},
|
||||
"resume": {
|
||||
"menu": {
|
||||
"delete": "מחיקה",
|
||||
"duplicate": "שכפל",
|
||||
"open": "פתוח",
|
||||
"rename": "שנה שם",
|
||||
"share-link": "שתף קישור",
|
||||
"tooltips": {
|
||||
"delete": "האם אתה בטוח שברצונך להסיר תכונה זו? זה בלתי הפיך.",
|
||||
"share-link": "עליך לשנות את החשיפה של קורות החיים שלך לציבורי כדי להפוך אותם לגלויים לאחרים."
|
||||
}
|
||||
},
|
||||
"timestamp": "עודכן לאחרונה {{timestamp}}"
|
||||
},
|
||||
"title": "לוּחַ מַחווָנִים"
|
||||
}
|
||||
41
client/public/locales/he/landing.json
Normal file
41
client/public/locales/he/landing.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"actions": {
|
||||
"app": "עבור לאפליקציה",
|
||||
"login": "התחברות",
|
||||
"logout": "להתנתק",
|
||||
"register": "הירשם"
|
||||
},
|
||||
"features": {
|
||||
"heading": "תכונות",
|
||||
"list": {
|
||||
"ads": "אין פרסום",
|
||||
"export": "ייצא את קורות החיים שלך לפורמט JSON או PDF",
|
||||
"free": "חופשי לנצח",
|
||||
"import": "יבא נתונים מ-LinkedIn, קורות חיים של JSON",
|
||||
"languages": "נגיש במספר שפות",
|
||||
"more": "ותכונות מרגשות הרבה יותר, <1>קרא הכל כאן</1>",
|
||||
"tracking": "אין מעקב אחר משתמשים"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"heading": "קישורים",
|
||||
"links": {
|
||||
"donate": "לִתְרוֹם",
|
||||
"github": "קוד מקור",
|
||||
"privacy": "מדיניות פרטיות",
|
||||
"service": "תנאי השירות"
|
||||
}
|
||||
},
|
||||
"screenshots": {
|
||||
"heading": "צילומי מסך"
|
||||
},
|
||||
"testimonials": {
|
||||
"heading": "המלצות",
|
||||
"body": "טוב או רע, אשמח לשמוע את דעתכם על קורות חיים ריאקטיביים ואיך הייתה החוויה עבורכם.<br/>הנה כמה מההודעות שנשלחו על ידי משתמשים ברחבי העולם.",
|
||||
"contact": "אתה יכול ליצור איתי קשר דרך <1>המייל שלי</1> או דרך טופס יצירת הקשר ב<3>אתר האינטרנט שלי</3> ."
|
||||
},
|
||||
"summary": {
|
||||
"body": "Reactive Resume הוא בונה קורות חיים חינמי וקוד פתוח שנבנה כדי להפוך את המשימות השגרתיות של יצירה, עדכון ושיתוף של קורות החיים שלך לקלות כמו 1, 2, 3. עם האפליקציה הזו, אתה יכול ליצור מספר קורות חיים, לשתף אותם עם מגייסים או חברים דרך קישור ייחודי והדפיס אותו כקובץ PDF, הכל בחינם, ללא פרסומות, ללא מעקב, מבלי לאבד את השלמות והפרטיות של הנתונים שלך.",
|
||||
"heading": "סיכום"
|
||||
}
|
||||
}
|
||||
136
client/public/locales/he/modals.json
Normal file
136
client/public/locales/he/modals.json
Normal file
@ -0,0 +1,136 @@
|
||||
{
|
||||
"auth": {
|
||||
"forgot-password": {
|
||||
"actions": {
|
||||
"send-email": "שלח אימייל איפוס סיסמה"
|
||||
},
|
||||
"body": "פשוט הזן את כתובת האימייל המשויכת לחשבון שברצונך לשחזר.",
|
||||
"form": {
|
||||
"email": {
|
||||
"label": "כתובת דוא\"ל"
|
||||
}
|
||||
},
|
||||
"heading": "שכחת ססמה?",
|
||||
"help-text": "אם החשבון קיים, תקבל אימייל עם קישור לאיפוס הסיסמה שלך."
|
||||
},
|
||||
"login": {
|
||||
"actions": {
|
||||
"login": "התחברות",
|
||||
"google": "התחבר עם גוגל"
|
||||
},
|
||||
"body": "אנא הזן את שם המשתמש והסיסמה המשויכים לחשבונך כדי להתחבר ולגשת, לנהל ולשתף את קורות החיים שלך.",
|
||||
"form": {
|
||||
"password": {
|
||||
"label": "סיסמה"
|
||||
},
|
||||
"username": {
|
||||
"help-text": "אתה יכול גם להזין את כתובת הדוא\"ל שלך",
|
||||
"label": "שם משתמש"
|
||||
}
|
||||
},
|
||||
"heading": "התחבר לחשבונך",
|
||||
"recover-text": "במקרה ששכחת את הסיסמה שלך, תוכל <1>לשחזר את חשבונך</1> כאן.",
|
||||
"register-text": "אם אין לך אחד, אתה יכול <1>ליצור חשבון</1> כאן."
|
||||
},
|
||||
"register": {
|
||||
"actions": {
|
||||
"register": "הירשם",
|
||||
"google": "הירשם בגוגל"
|
||||
},
|
||||
"body": "אנא הזן את המידע האישי שלך כדי ליצור חשבון.",
|
||||
"form": {
|
||||
"confirm-password": {
|
||||
"label": "אשר סיסמה"
|
||||
},
|
||||
"email": {
|
||||
"label": "כתובת דוא\"ל"
|
||||
},
|
||||
"name": {
|
||||
"label": "שם מלא"
|
||||
},
|
||||
"password": {
|
||||
"label": "סיסמה"
|
||||
},
|
||||
"username": {
|
||||
"label": "שם משתמש"
|
||||
}
|
||||
},
|
||||
"heading": "צור חשבון",
|
||||
"loginText": "אם כבר יש לך חשבון, אתה יכול <1>להתחבר כאן</1> ."
|
||||
},
|
||||
"reset-password": {
|
||||
"actions": {
|
||||
"set-password": "הגדר סיסמה חדשה"
|
||||
},
|
||||
"body": "הזן סיסמה חדשה לחשבון שלך.",
|
||||
"form": {
|
||||
"confirm-password": {
|
||||
"label": "אשר סיסמה"
|
||||
},
|
||||
"password": {
|
||||
"label": "סיסמה"
|
||||
}
|
||||
},
|
||||
"heading": "אפס את הסיסמה שלך"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"create-resume": {
|
||||
"actions": {
|
||||
"create-resume": "צור קורות חיים"
|
||||
},
|
||||
"body": "התחל לבנות את קורות החיים שלך על ידי מתן שם לקובץ. זה יכול להיות בהתייחסות לתפקיד שאתה מגיש מועמדות אליו, או רק החטיף האהוב עליך.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "שם"
|
||||
},
|
||||
"public": {
|
||||
"label": "האם נגיש לציבור?"
|
||||
},
|
||||
"slug": {
|
||||
"label": "סלאג"
|
||||
}
|
||||
},
|
||||
"heading": "צור קורות חיים חדשים"
|
||||
},
|
||||
"import-external": {
|
||||
"heading": "ייבוא ממקורות חיצוניים",
|
||||
"json-resume": {
|
||||
"actions": {
|
||||
"upload-json": "העלה JSON"
|
||||
},
|
||||
"body": "אם יש לך <1>קורות חיים של JSON מאומת</1> מוכן לפעולה, אתה יכול להשתמש בו כדי לעקוב במהירות את הפיתוח שלך בקורות חיים ריאקטיביים. לחץ על הכפתור למטה והעלה קובץ JSON חוקי כדי להתחיל.",
|
||||
"heading": "ייבוא מ-JSON קורות חיים"
|
||||
},
|
||||
"linkedin": {
|
||||
"actions": {
|
||||
"upload-archive": "העלה ארכיון ZIP"
|
||||
},
|
||||
"body": "אתה יכול לחסוך זמן על ידי ייצוא הנתונים שלך מ-LinkedIn ושימוש בהם למילוי אוטומטי של שדות בקורות חיים תגובתיים. עבור אל <1>פרטיות נתונים</1> מדור בלינקדאין ובקש ארכיון של הנתונים שלך. ברגע שהוא זמין, העלה את קובץ ה-ZIP למטה.",
|
||||
"heading": "ייבוא מ-LinkedIn"
|
||||
},
|
||||
"reactive-resume": {
|
||||
"actions": {
|
||||
"upload-json": "העלה JSON",
|
||||
"upload-json-v2": "העלה JSON מגרסה 2"
|
||||
},
|
||||
"body": "אם יש לך JSON שיוצא עם הגרסה הנוכחית של Reactive Resume, תוכל לייבא אותו בחזרה לכאן כדי לקבל שוב גרסה הניתנת לעריכה.",
|
||||
"heading": "ייבא מ- Reactive Resume"
|
||||
}
|
||||
},
|
||||
"rename-resume": {
|
||||
"actions": {
|
||||
"rename-resume": "שנה את שם קורות החיים"
|
||||
},
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "שם"
|
||||
},
|
||||
"slug": {
|
||||
"label": "סלאג"
|
||||
}
|
||||
},
|
||||
"heading": "שנה את שם קורות החיים שלך"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
"present": "Sekarang"
|
||||
},
|
||||
"subtitle": "Pembuat resume open source dan gratis.",
|
||||
"title": "Reactive Resume",
|
||||
"title": "\"Reactive Resume\"",
|
||||
"toast": {
|
||||
"error": {
|
||||
"upload-file-size": "Harap unggah hanya file di bawah 2 megabytes.",
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"title": "Buat Resume Baru"
|
||||
},
|
||||
"import-external": {
|
||||
"subtitle": "LinkedIn, JSON Resume, Reactive Resume",
|
||||
"subtitle": "LinkedIn, Resume JSON, Reactive Resume",
|
||||
"title": "Impor dari sumber luar"
|
||||
},
|
||||
"resume": {
|
||||
|
||||
25
client/public/locales/no/dashboard.json
Normal file
25
client/public/locales/no/dashboard.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"create-resume": {
|
||||
"subtitle": "Start fra begynnelsen",
|
||||
"title": "Opprett ny CV"
|
||||
},
|
||||
"import-external": {
|
||||
"subtitle": "LinkedIn, JSON Resume, Reactive Resume",
|
||||
"title": "Importer fra eksterne kilder"
|
||||
},
|
||||
"resume": {
|
||||
"menu": {
|
||||
"delete": "Slett",
|
||||
"duplicate": "Dupliser",
|
||||
"open": "Åpen",
|
||||
"rename": "Endre navn",
|
||||
"share-link": "Del lenke",
|
||||
"tooltips": {
|
||||
"delete": "Er du sikker på at du vil slette dette resymeet? Dette er en irreversibel handling.",
|
||||
"share-link": "Du må endre synligheten til resymeet ditt til offentlig for å gjøre det synlig for andre."
|
||||
}
|
||||
},
|
||||
"timestamp": "Sist oppdatert for {{timestamp}} siden"
|
||||
},
|
||||
"title": "Oversikt"
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
"help-text": "Esta seção suporta formatação <1>markdown</1>."
|
||||
},
|
||||
"date": {
|
||||
"present": "presente"
|
||||
"present": "Presente"
|
||||
},
|
||||
"subtitle": "Gerador de currículos gratuito e de código aberto.",
|
||||
"title": "Reactive Resume",
|
||||
|
||||
361
client/public/locales/sr/builder.json
Normal file
361
client/public/locales/sr/builder.json
Normal file
@ -0,0 +1,361 @@
|
||||
{
|
||||
"common": {
|
||||
"actions": {
|
||||
"add": "Dodaj Novi {{token}}",
|
||||
"delete": "Obriši {{token}}",
|
||||
"edit": "Ažuriraj {{token}}"
|
||||
},
|
||||
"columns": {
|
||||
"heading": "Kolone",
|
||||
"tooltip": "Promeni broj kolona"
|
||||
},
|
||||
"form": {
|
||||
"date": {
|
||||
"label": "Datum"
|
||||
},
|
||||
"description": {
|
||||
"label": "Opis"
|
||||
},
|
||||
"email": {
|
||||
"label": "Imejl Adresa"
|
||||
},
|
||||
"end-date": {
|
||||
"help-text": "Ostavi ovo polje prazno, ukoliko još postoji",
|
||||
"label": "Datum kraja"
|
||||
},
|
||||
"keywords": {
|
||||
"label": "Ključne reči"
|
||||
},
|
||||
"level": {
|
||||
"label": "Nivo"
|
||||
},
|
||||
"levelNum": {
|
||||
"label": "Nivo (Broj)"
|
||||
},
|
||||
"name": {
|
||||
"label": "Ime"
|
||||
},
|
||||
"phone": {
|
||||
"label": "Broj Telefona"
|
||||
},
|
||||
"position": {
|
||||
"label": "Pozicija"
|
||||
},
|
||||
"start-date": {
|
||||
"label": "Datum Početka"
|
||||
},
|
||||
"subtitle": {
|
||||
"label": "Podnaslov"
|
||||
},
|
||||
"summary": {
|
||||
"label": "Rezime"
|
||||
},
|
||||
"title": {
|
||||
"label": "Naslov"
|
||||
},
|
||||
"url": {
|
||||
"label": "Veb Sajt"
|
||||
}
|
||||
},
|
||||
"glossary": {
|
||||
"page": "Stranica"
|
||||
},
|
||||
"list": {
|
||||
"actions": {
|
||||
"delete": "Obriši",
|
||||
"duplicate": "Dupliraj",
|
||||
"edit": "Edituj"
|
||||
},
|
||||
"empty-text": "Ova lista je prazna."
|
||||
},
|
||||
"tooltip": {
|
||||
"delete-item": "Da li sigurno želiš da izbrišeš ovu stavku? Ovo je nepovratna akcija.",
|
||||
"delete-section": "Obriši Sekciju",
|
||||
"rename-section": "Preimenuj Sekciju",
|
||||
"toggle-visibility": "Prebaci Vidljivost"
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"tooltip": {
|
||||
"center-artboard": "Centriraj Kanvas",
|
||||
"copy-link": "Kopiraj link u rezime",
|
||||
"export-pdf": "Eksportuj PDF",
|
||||
"toggle-orientation": "Uključi/Isključi Orijentaciju Stranice",
|
||||
"toggle-page-break-line": "Uključi/Isključi liniju preloma stranice",
|
||||
"toggle-sidebars": "Uključi/Isključi Sidebar",
|
||||
"zoom-in": "Zumiraj",
|
||||
"zoom-out": "Odzumiraj"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"menu": {
|
||||
"delete": "Obriši",
|
||||
"duplicate": "Dupliraj",
|
||||
"rename": "Preimenuj",
|
||||
"share-link": "Podeli Link",
|
||||
"tooltips": {
|
||||
"delete": "Da li sigurno želiš da obrišeš ovaj rezime? Ovo je nepovratna akcija.",
|
||||
"share-link": "Moraš da promeniš vidljivost rezimea na javno kako bi bio vidljiv drugima."
|
||||
}
|
||||
}
|
||||
},
|
||||
"leftSidebar": {
|
||||
"sections": {
|
||||
"awards": {
|
||||
"form": {
|
||||
"awarder": {
|
||||
"label": "Dodelio nagradu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"basics": {
|
||||
"actions": {
|
||||
"photo-filters": "Filteri za Slike"
|
||||
},
|
||||
"heading": "Osnovno",
|
||||
"headline": {
|
||||
"label": "Naslov"
|
||||
},
|
||||
"name": {
|
||||
"label": "Puno Ime"
|
||||
},
|
||||
"birthdate": {
|
||||
"label": "Datum Rođenja"
|
||||
},
|
||||
"photo-filters": {
|
||||
"effects": {
|
||||
"border": {
|
||||
"label": "Okvir"
|
||||
},
|
||||
"grayscale": {
|
||||
"label": "Sivi Ton"
|
||||
},
|
||||
"heading": "Efekti"
|
||||
},
|
||||
"shape": {
|
||||
"heading": "Oblik"
|
||||
},
|
||||
"size": {
|
||||
"heading": "Veličina (u pikselima)"
|
||||
}
|
||||
},
|
||||
"photo-upload": {
|
||||
"tooltip": {
|
||||
"remove": "Obriši Sliku",
|
||||
"upload": "Učitaj Sliku"
|
||||
}
|
||||
}
|
||||
},
|
||||
"certifications": {
|
||||
"form": {
|
||||
"issuer": {
|
||||
"label": "Izdavač"
|
||||
}
|
||||
}
|
||||
},
|
||||
"education": {
|
||||
"form": {
|
||||
"area-study": {
|
||||
"label": "Oblast Edukacije"
|
||||
},
|
||||
"courses": {
|
||||
"label": "Kursevi"
|
||||
},
|
||||
"degree": {
|
||||
"label": "Stepen"
|
||||
},
|
||||
"grade": {
|
||||
"label": "Ocena"
|
||||
},
|
||||
"institution": {
|
||||
"label": "Institucija"
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"address": {
|
||||
"label": "Adresa"
|
||||
},
|
||||
"city": {
|
||||
"label": "Grad"
|
||||
},
|
||||
"country": {
|
||||
"label": "Zemlja"
|
||||
},
|
||||
"heading": "Lokacija",
|
||||
"postal-code": {
|
||||
"label": "Poštanski Broj"
|
||||
},
|
||||
"region": {
|
||||
"label": "Region"
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"form": {
|
||||
"network": {
|
||||
"label": "Mreža"
|
||||
},
|
||||
"username": {
|
||||
"label": "Korisničko ime"
|
||||
}
|
||||
},
|
||||
"heading": "Profili",
|
||||
"heading_one": "Profil"
|
||||
},
|
||||
"publications": {
|
||||
"form": {
|
||||
"publisher": {
|
||||
"label": "Izdavač"
|
||||
}
|
||||
}
|
||||
},
|
||||
"references": {
|
||||
"form": {
|
||||
"relationship": {
|
||||
"label": "Veza"
|
||||
}
|
||||
}
|
||||
},
|
||||
"section": {
|
||||
"heading": "Sekcija"
|
||||
},
|
||||
"volunteer": {
|
||||
"form": {
|
||||
"organization": {
|
||||
"label": "Organizacija"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rightSidebar": {
|
||||
"sections": {
|
||||
"css": {
|
||||
"heading": "Prilagodi CSS"
|
||||
},
|
||||
"export": {
|
||||
"heading": "Eksportuj",
|
||||
"json": {
|
||||
"primary": "JSON",
|
||||
"secondary": "Preuzmi JSON verziju tvog rezimea koja se može importovati nazad u Reactive Resume."
|
||||
},
|
||||
"pdf": {
|
||||
"loading": {
|
||||
"primary": "Generišem PDF",
|
||||
"secondary": "Sačekaj dok se tvoj PDF generiše, ovo može da potraje do 15 sekundi."
|
||||
},
|
||||
"normal": {
|
||||
"primary": "PDF",
|
||||
"secondary": "Preuzmi PDF verziju rezimea koju možeš da štampaš i pošalješ za svoj posao iz snova. Ovaj fajl se ne može importovati ponovo kako bi se ponovo ažurirao."
|
||||
}
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"heading": "Izgled",
|
||||
"tooltip": {
|
||||
"reset-layout": "Resetuj izgled"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"bugs-features": {
|
||||
"body": "Nešto de sprečava da napraviš svoj rezime? Ili imaš neku super ideju kao predlog? Kreiraj task na GitHub-u za početak.",
|
||||
"button": "GitHub Problemi",
|
||||
"heading": "Bagovi? Zahtevi za novu funkcionalnost?"
|
||||
},
|
||||
"donate": {
|
||||
"body": "Ako ti se sviđa Reactive Resume, razmotri o donaciji kako bi aplikacija nastavila da funkcioniše i bude dostupna, bez reklama i besplatna zauvek.",
|
||||
"button": "Kupi mi kafu",
|
||||
"heading": "Doniraj za Reactive Resume"
|
||||
},
|
||||
"github": "Izvorni Kod",
|
||||
"heading": "Linkovi"
|
||||
},
|
||||
"settings": {
|
||||
"global": {
|
||||
"date": {
|
||||
"primary": "Datum",
|
||||
"secondary": "Format datuma koji se koristi u aplikaciji"
|
||||
},
|
||||
"heading": "Globalno",
|
||||
"language": {
|
||||
"primary": "Jezik",
|
||||
"secondary": "Jezika prikaza za korišćenje u celoj aplikaciji"
|
||||
},
|
||||
"theme": {
|
||||
"primary": "Tema"
|
||||
}
|
||||
},
|
||||
"heading": "Podešavanja",
|
||||
"page": {
|
||||
"break-line": {
|
||||
"primary": "Prelomi Redova",
|
||||
"secondary": "Pokaži liniju na svakoj stranici kako bi se obeležila visina A4 stranice"
|
||||
},
|
||||
"heading": "Strana",
|
||||
"orientation": {
|
||||
"disabled": "Nema efekat kada postoji samo jedna stranica",
|
||||
"primary": "Orijentacija",
|
||||
"secondary": "Da li prikazujem stranice horizontalno ili vertikalno"
|
||||
}
|
||||
},
|
||||
"resume": {
|
||||
"heading": "Rezime",
|
||||
"reset": {
|
||||
"primary": "Resetuje sve",
|
||||
"secondary": "Previše grešaka? Klikni ovde da resetuješ sve izmene i počneš izpočetka. Vodi računa, ova akcija se ne može promeniti."
|
||||
},
|
||||
"sample": {
|
||||
"primary": "Učitaj podatke kao primer",
|
||||
"secondary": "Ne znaš gde da počneš? Klikni ovde da učitaš podatke kao primer i vidiš kako ceo rezime može da izgleda."
|
||||
}
|
||||
}
|
||||
},
|
||||
"sharing": {
|
||||
"heading": "Deljenje",
|
||||
"short-url": {
|
||||
"label": "Kao Kratak URL"
|
||||
},
|
||||
"visibility": {
|
||||
"subtitle": "Dozvoli svakom sa linkom da pogleda tvoj rezime",
|
||||
"title": "Javno"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"heading": "Šabloni"
|
||||
},
|
||||
"theme": {
|
||||
"form": {
|
||||
"background": {
|
||||
"label": "Pozadina"
|
||||
},
|
||||
"primary": {
|
||||
"label": "Glavni"
|
||||
},
|
||||
"text": {
|
||||
"label": "Tekst"
|
||||
}
|
||||
},
|
||||
"heading": "Tema"
|
||||
},
|
||||
"typography": {
|
||||
"form": {
|
||||
"font-family": {
|
||||
"label": "Porodica Fontova"
|
||||
},
|
||||
"font-size": {
|
||||
"label": "Veličina Fonta"
|
||||
}
|
||||
},
|
||||
"heading": "Tipografija",
|
||||
"widgets": {
|
||||
"body": {
|
||||
"label": "Sadržaj"
|
||||
},
|
||||
"headings": {
|
||||
"label": "Naslovi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,7 +19,7 @@ export const dateFormatOptions: string[] = [
|
||||
'YYYY',
|
||||
];
|
||||
|
||||
export const getRelativeTime = (timestamp: dayjs.ConfigType): string => dayjs(timestamp).toNow(true);
|
||||
export const getRelativeTime = (timestamp: dayjs.ConfigType): string => dayjs(timestamp).utc().toNow(true);
|
||||
|
||||
export const formatDateString = (date: string | DateRange, formatStr: string): string | null => {
|
||||
const presentString = i18n?.t<string>('common.date.present') ?? '';
|
||||
@ -28,9 +28,9 @@ export const formatDateString = (date: string | DateRange, formatStr: string): s
|
||||
|
||||
// If `date` is a string
|
||||
if (isString(date)) {
|
||||
if (!dayjs(date).isValid()) return null;
|
||||
if (!dayjs(date).utc().utc().isValid()) return null;
|
||||
|
||||
return dayjs(date).format(formatStr);
|
||||
return dayjs(date).utc().format(formatStr);
|
||||
}
|
||||
|
||||
// If `date` is a DateRange
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@ -7,6 +8,7 @@ const DateWrapper: React.FC<React.PropsWithChildren<unknown>> = ({ children }) =
|
||||
const { locale } = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
// Locales
|
||||
|
||||
@ -8,8 +8,6 @@ services:
|
||||
- POSTGRES_DB=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
|
||||
@ -3,3 +3,9 @@ sidebar_position: 1
|
||||
---
|
||||
|
||||
# Creating an account
|
||||
|
||||
Enter your basic information or sign up with a Google account.
|
||||
|
||||
<a href="https://rxresu.me" target="_blank">
|
||||
<img src="https://res.cloudinary.com/dn2mupqo0/image/upload/v1655879734/Register_lnoueb.png" type="image"></img>
|
||||
</a>
|
||||
|
||||
@ -3,3 +3,22 @@ sidebar_position: 2
|
||||
---
|
||||
|
||||
# Create a new resume
|
||||
|
||||
|
||||
To create a new resume from scratch, click on the selected part.
|
||||
|
||||
<a href="https://rxresu.me/dashboard">
|
||||
<img src="https://res.cloudinary.com/dn2mupqo0/image/upload/v1655880844/CreateNew_kxvi9x.png" type="image"></img>
|
||||
</a>
|
||||
|
||||
<p>
|
||||
After you click on it, enter name and select whether you want it publicly accessible
|
||||
<img align="center" src="https://res.cloudinary.com/dn2mupqo0/image/upload/v1655884469/on-button_a5kfbz.png" height='25' type="image"></img> or not
|
||||
<img align="center" src="https://res.cloudinary.com/dn2mupqo0/image/upload/v1655884949/off-button_rrkz3g.png" height='25' type="image"></img> . You can also change it later from the sharing <a href="https://res.cloudinary.com/dn2mupqo0/image/upload/v1655889311/toggle_jcmfix.gif">see where</a>.
|
||||
</p>
|
||||
|
||||
<h3> Now it's look like ⚡</h3>
|
||||
|
||||
<a href="https://rxresu.me/dashboard">
|
||||
<img src="https://res.cloudinary.com/dn2mupqo0/image/upload/v1655882355/Screenshot_2022-06-22_at_12.48.42_PM_dx6714.png" type="image"></img>
|
||||
</a>
|
||||
|
||||
@ -14,14 +14,14 @@
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.13.1",
|
||||
"@docusaurus/core": "2.0.0-beta.21",
|
||||
"@docusaurus/preset-classic": "2.0.0-beta.21",
|
||||
"@mdx-js/react": "2.1.2",
|
||||
"clsx": "^1.1.1",
|
||||
"prism-react-renderer": "^1.3.3",
|
||||
"react": ">=16.13.1 <17.0.0 || >=17.0.0 <18.0.0",
|
||||
"react-dom": ">=16.8.4 <17.0.0 || >=17.0.0 <18.0.0"
|
||||
"@algolia/client-search": "^4.14.2",
|
||||
"@docusaurus/core": "2.0.0-rc.1",
|
||||
"@docusaurus/preset-classic": "2.0.0-rc.1",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"clsx": "^1.2.1",
|
||||
"prism-react-renderer": "^1.3.5",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@ -36,7 +36,7 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": ">=16.8.0 <19.0.0",
|
||||
"@types/react": "^17.0.2",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
25
package-lock.json
generated
25
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "reactive-resume",
|
||||
"version": "3.4.6",
|
||||
"version": "3.5.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "reactive-resume",
|
||||
"version": "3.4.6",
|
||||
"version": "3.5.1",
|
||||
"workspaces": [
|
||||
"schema",
|
||||
"client",
|
||||
@ -28886,6 +28886,21 @@
|
||||
},
|
||||
"server/*": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@next/swc-freebsd-x64": {
|
||||
"version": "12.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.0.tgz",
|
||||
"integrity": "sha512-gRiAw8g3Akf6niTDLEm1Emfa7jXDjvaAj/crDO8hKASKA4Y1fS4kbi/tyWw5VtoFI4mUzRmCPmZ8eL0tBSG58A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@ -49808,6 +49823,12 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz",
|
||||
"integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA=="
|
||||
},
|
||||
"@next/swc-freebsd-x64": {
|
||||
"version": "12.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.0.tgz",
|
||||
"integrity": "sha512-gRiAw8g3Akf6niTDLEm1Emfa7jXDjvaAj/crDO8hKASKA4Y1fS4kbi/tyWw5VtoFI4mUzRmCPmZ8eL0tBSG58A==",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
package.json
15
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "reactive-resume",
|
||||
"version": "3.4.6",
|
||||
"version": "3.5.1",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"schema",
|
||||
@ -34,20 +34,17 @@
|
||||
"start": "env-cmd --silent concurrently --kill-others \"pnpm run start:*\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.113.0",
|
||||
"@docusaurus/core": "^2.0.0-beta.21",
|
||||
"@docusaurus/preset-classic": "^2.0.0-beta.21",
|
||||
"concurrently": "^7.2.2",
|
||||
"concurrently": "^7.3.0",
|
||||
"env-cmd": "^10.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.28.0",
|
||||
"@typescript-eslint/parser": "^5.28.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.31.0",
|
||||
"@typescript-eslint/parser": "^5.31.0",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"eslint": "^8.18.0",
|
||||
"eslint": "^8.20.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"husky": "^8.0.1",
|
||||
|
||||
7642
pnpm-lock.yaml
generated
7642
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
"lint": "eslint --fix --ext .ts ./src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.18.0",
|
||||
"eslint": "^8.20.0",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,29 +10,29 @@
|
||||
"lint": "eslint --fix --ext .ts ./src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.113.0",
|
||||
"@nestjs/axios": "^0.0.8",
|
||||
"@nestjs/common": "^8.4.7",
|
||||
"@nestjs/config": "^2.1.0",
|
||||
"@nestjs/core": "^8.4.7",
|
||||
"@nestjs/jwt": "^8.0.1",
|
||||
"@nestjs/mapped-types": "^1.0.1",
|
||||
"@nestjs/passport": "^8.2.2",
|
||||
"@nestjs/platform-express": "^8.4.7",
|
||||
"@nestjs/schedule": "^2.0.1",
|
||||
"@nestjs/serve-static": "^2.2.2",
|
||||
"@nestjs/terminus": "^8.0.8",
|
||||
"@nestjs/typeorm": "^8.1.4",
|
||||
"@aws-sdk/client-s3": "^3.137.0",
|
||||
"@nestjs/axios": "^0.1.0",
|
||||
"@nestjs/common": "^9.0.7",
|
||||
"@nestjs/config": "^2.2.0",
|
||||
"@nestjs/core": "^9.0.7",
|
||||
"@nestjs/jwt": "^9.0.0",
|
||||
"@nestjs/mapped-types": "^1.1.0",
|
||||
"@nestjs/passport": "^9.0.0",
|
||||
"@nestjs/platform-express": "^9.0.7",
|
||||
"@nestjs/schedule": "^2.1.0",
|
||||
"@nestjs/serve-static": "^3.0.0",
|
||||
"@nestjs/terminus": "^9.0.0",
|
||||
"@nestjs/typeorm": "^9.0.0",
|
||||
"@sendgrid/mail": "^7.7.0",
|
||||
"@types/passport": "^1.0.9",
|
||||
"bcrypt": "^5.0.1",
|
||||
"cache-manager": "^4.0.1",
|
||||
"cache-manager": "^4.1.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.13.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"csvtojson": "^2.0.10",
|
||||
"dayjs": "^1.11.3",
|
||||
"google-auth-library": "^8.0.2",
|
||||
"dayjs": "^1.11.4",
|
||||
"google-auth-library": "^8.1.1",
|
||||
"joi": "^17.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"multer": "^1.4.4",
|
||||
@ -43,30 +43,30 @@
|
||||
"passport-local": "^1.0.0",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright-chromium": "^1.22.2",
|
||||
"playwright-chromium": "^1.24.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.5.5",
|
||||
"typeorm": "0.3.6",
|
||||
"rxjs": "^7.5.6",
|
||||
"typeorm": "0.3.7",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^8.2.6",
|
||||
"@nestjs/schematics": "^8.0.11",
|
||||
"@nestjs/cli": "^9.0.0",
|
||||
"@nestjs/schematics": "^9.0.1",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^18.0.0",
|
||||
"eslint": "^8.18.0",
|
||||
"@types/node": "^18.6.2",
|
||||
"eslint": "^8.20.0",
|
||||
"prettier": "^2.7.1",
|
||||
"source-map-support": "^0.5.21",
|
||||
"ts-loader": "^9.3.0",
|
||||
"ts-node": "^10.8.1",
|
||||
"ts-loader": "^9.3.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsconfig-paths": "^4.0.0",
|
||||
"typescript": "^4.7.4",
|
||||
"webpack": "^5.73.0"
|
||||
"webpack": "^5.74.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,5 +7,4 @@ export default registerAs('storage', () => ({
|
||||
urlPrefix: process.env.STORAGE_URL_PREFIX,
|
||||
accessKey: process.env.STORAGE_ACCESS_KEY,
|
||||
secretKey: process.env.STORAGE_SECRET_KEY,
|
||||
s3Enabled: process.env.STORAGE_S3_ENABLED,
|
||||
}));
|
||||
|
||||
@ -15,6 +15,7 @@ import {
|
||||
} from '@reactive-resume/schema';
|
||||
import csv from 'csvtojson';
|
||||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import { readFile, unlink } from 'fs/promises';
|
||||
import { cloneDeep, get, isEmpty, merge } from 'lodash';
|
||||
import StreamZip from 'node-stream-zip';
|
||||
@ -28,7 +29,9 @@ import { ResumeService } from '@/resume/resume.service';
|
||||
|
||||
@Injectable()
|
||||
export class IntegrationsService {
|
||||
constructor(private resumeService: ResumeService) {}
|
||||
constructor(private resumeService: ResumeService) {
|
||||
dayjs.extend(utc);
|
||||
}
|
||||
|
||||
async linkedIn(userId: number, path: string): Promise<ResumeEntity> {
|
||||
let archive: StreamZip.StreamZipAsync;
|
||||
@ -39,7 +42,7 @@ export class IntegrationsService {
|
||||
const resume: Partial<Resume> = cloneDeep(defaultState);
|
||||
|
||||
// Basics
|
||||
const timestamp = dayjs().format(FILENAME_TIMESTAMP);
|
||||
const timestamp = dayjs().utc().format(FILENAME_TIMESTAMP);
|
||||
merge<Partial<Resume>, DeepPartial<Resume>>(resume, {
|
||||
name: `Imported from LinkedIn (${timestamp})`,
|
||||
slug: `imported-from-linkedin-${timestamp}`,
|
||||
@ -269,7 +272,7 @@ export class IntegrationsService {
|
||||
const resume: Partial<Resume> = cloneDeep(defaultState);
|
||||
|
||||
// Metadata
|
||||
const timestamp = dayjs().format(FILENAME_TIMESTAMP);
|
||||
const timestamp = dayjs().utc().format(FILENAME_TIMESTAMP);
|
||||
merge<Partial<Resume>, DeepPartial<Resume>>(resume, {
|
||||
name: `Imported from JSON Resume (${timestamp})`,
|
||||
slug: `imported-from-json-resume-${timestamp}`,
|
||||
@ -604,7 +607,7 @@ export class IntegrationsService {
|
||||
const resume: Partial<Resume> = cloneDeep(jsonResume);
|
||||
|
||||
// Metadata
|
||||
const timestamp = dayjs().format(FILENAME_TIMESTAMP);
|
||||
const timestamp = dayjs().utc().format(FILENAME_TIMESTAMP);
|
||||
merge<Partial<Resume>, DeepPartial<Resume>>(resume, {
|
||||
name: `Imported from Reactive Resume (${timestamp})`,
|
||||
slug: `imported-from-reactive-resume-${timestamp}`,
|
||||
@ -625,7 +628,7 @@ export class IntegrationsService {
|
||||
const resume: Partial<Resume> = cloneDeep(defaultState);
|
||||
|
||||
// Metadata
|
||||
const timestamp = dayjs().format(FILENAME_TIMESTAMP);
|
||||
const timestamp = dayjs().utc().format(FILENAME_TIMESTAMP);
|
||||
merge<Partial<Resume>, DeepPartial<Resume>>(resume, {
|
||||
name: `Imported from Reactive Resume V2 (${timestamp})`,
|
||||
slug: `imported-from-reactive-resume-v2-${timestamp}`,
|
||||
@ -948,6 +951,6 @@ export class IntegrationsService {
|
||||
}
|
||||
|
||||
private parseDate = (date: string): string => {
|
||||
return isEmpty(date) ? '' : dayjs(date).toISOString();
|
||||
return isEmpty(date) ? '' : dayjs(date).utc().toISOString();
|
||||
};
|
||||
}
|
||||
|
||||
@ -7,7 +7,11 @@ import { User } from '@/users/entities/user.entity';
|
||||
@Injectable()
|
||||
export class MailService {
|
||||
constructor(private configService: ConfigService) {
|
||||
SendGrid.setApiKey(this.configService.get<string>('sendgrid.apiKey'));
|
||||
const sendGridApiKey = this.configService.get<string>('sendgrid.apiKey');
|
||||
|
||||
if (sendGridApiKey) {
|
||||
SendGrid.setApiKey(this.configService.get<string>('sendgrid.apiKey'));
|
||||
}
|
||||
}
|
||||
|
||||
async sendEmail(mail: SendGrid.MailDataRequired) {
|
||||
|
||||
@ -4,7 +4,7 @@ import { ConfigService } from '@nestjs/config';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Resume as ResumeSchema } from '@reactive-resume/schema';
|
||||
import fs from 'fs';
|
||||
import { pick, sample, set } from 'lodash';
|
||||
import { isEmpty, pick, sample, set } from 'lodash';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { extname } from 'path';
|
||||
import { Repository } from 'typeorm';
|
||||
@ -31,7 +31,8 @@ export class ResumeService {
|
||||
private configService: ConfigService,
|
||||
private usersService: UsersService
|
||||
) {
|
||||
this.s3Enabled = configService.get<string>('storage.s3Enabled') !== 'false';
|
||||
this.s3Enabled = !isEmpty(configService.get<string>('storage.bucket'));
|
||||
|
||||
if (this.s3Enabled) {
|
||||
this.s3Client = new S3({
|
||||
endpoint: configService.get<string>('storage.endpoint'),
|
||||
@ -237,6 +238,7 @@ export class ResumeService {
|
||||
|
||||
const filename = new Date().getTime() + extname(file.originalname);
|
||||
let updatedResume = null;
|
||||
|
||||
if (this.s3Enabled) {
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const key = `uploads/${userId}/${id}/${filename}`;
|
||||
@ -271,6 +273,7 @@ export class ResumeService {
|
||||
async deletePhoto(id: number, userId: number) {
|
||||
const resume = await this.findOne(id, userId);
|
||||
const publicUrl = resume.basics.photo.url;
|
||||
|
||||
if (this.s3Enabled) {
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const key = publicUrl.replace(urlPrefix, '');
|
||||
@ -291,6 +294,7 @@ export class ResumeService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const updatedResume = set(resume, 'basics.photo.url', '');
|
||||
|
||||
return this.resumeRepository.save<Resume>(updatedResume);
|
||||
|
||||
Reference in New Issue
Block a user