Compare commits

...

357 Commits

Author SHA1 Message Date
7137694832 update app version to 3.6.5 2022-08-29 20:44:24 +02:00
049de38da2 fix local storage upload of photo/avatar 2022-08-29 20:44:07 +02:00
17019e446b Update FUNDING.yml 2022-08-29 19:57:16 +02:00
d73ee7b7f8 reformat docker setup to remove traefik dependency 2022-08-29 09:03:23 +02:00
2c95dc2ac8 Merge pull request #990 from AymaneBoukrouh/main
update landing.json
2022-08-29 07:48:54 +02:00
e148dd3e82 Merge pull request #1 from AymaneBoukrouh/AymaneBoukrouh-fr-locale-fix
update landing.json
2022-08-28 21:42:43 +01:00
0aa2d61c55 update landing.json
Fix typo (mauvaiss -> mauvaise)
Fix innacuracy (pistage -> traçabilité), pistage (tracking) means car track, and not user tracking.
2022-08-28 21:40:07 +01:00
0b2c1ffd26 add ko, mr locales 2022-08-28 16:22:14 +02:00
a531e8cd89 Merge pull request #989 from AmruthPillai/i18n_main
New Crowdin updates
2022-08-28 15:50:51 +02:00
152e386141 New translations landing.json (Odia) 2022-08-28 15:50:22 +02:00
87189cd045 New translations landing.json (Kannada) 2022-08-28 15:50:21 +02:00
114b04a740 New translations landing.json (Malayalam) 2022-08-28 15:50:20 +02:00
383cde53df New translations landing.json (Bengali) 2022-08-28 15:50:19 +02:00
9bf98d3c49 New translations landing.json (Tamil) 2022-08-28 15:50:18 +02:00
e62f0a3f5e New translations landing.json (Persian) 2022-08-28 15:50:17 +02:00
10fb7b143a New translations landing.json (Indonesian) 2022-08-28 15:50:16 +02:00
67ba58e798 New translations landing.json (Vietnamese) 2022-08-28 15:50:15 +02:00
179cf99f83 New translations landing.json (Chinese Simplified) 2022-08-28 15:50:14 +02:00
81a51d487b New translations landing.json (Turkish) 2022-08-28 15:50:13 +02:00
b41b50565a New translations landing.json (Hindi) 2022-08-28 15:50:13 +02:00
8cd073eb62 New translations landing.json (Swedish) 2022-08-28 15:50:12 +02:00
f4f8502703 New translations landing.json (Russian) 2022-08-28 15:50:03 +02:00
0d079d7b24 New translations landing.json (Portuguese) 2022-08-28 15:50:02 +02:00
167f7c902f New translations landing.json (Polish) 2022-08-28 15:49:50 +02:00
7c630df927 New translations landing.json (Dutch) 2022-08-28 15:49:49 +02:00
b391c561e5 New translations landing.json (Italian) 2022-08-28 15:49:48 +02:00
4dbe015fbf New translations landing.json (Hungarian) 2022-08-28 15:49:47 +02:00
bae35b2614 New translations landing.json (Hebrew) 2022-08-28 15:49:46 +02:00
8b7719a198 New translations landing.json (Finnish) 2022-08-28 15:49:46 +02:00
39cf238de3 New translations landing.json (Greek) 2022-08-28 15:49:45 +02:00
98855ae230 New translations landing.json (German) 2022-08-28 15:49:44 +02:00
ab92cbf21e New translations landing.json (Danish) 2022-08-28 15:49:43 +02:00
388ab4e29a New translations landing.json (Czech) 2022-08-28 15:49:42 +02:00
bb18c59018 New translations landing.json (Arabic) 2022-08-28 15:49:41 +02:00
217ab6ab93 New translations landing.json (French) 2022-08-28 15:49:40 +02:00
12690b33d7 New translations landing.json (Spanish) 2022-08-28 15:49:36 +02:00
bff5173701 New translations builder.json (Indonesian) 2022-08-28 15:49:34 +02:00
821813d90d New translations builder.json (Vietnamese) 2022-08-28 15:49:33 +02:00
b1d3c4da5b New translations builder.json (Chinese Simplified) 2022-08-28 15:49:32 +02:00
39f962b440 New translations builder.json (Swedish) 2022-08-28 15:49:31 +02:00
b1cfd4b7c8 New translations builder.json (Serbian (Cyrillic)) 2022-08-28 15:49:31 +02:00
c98d4a6004 New translations builder.json (Russian) 2022-08-28 15:49:30 +02:00
a5ec1f8609 New translations builder.json (Portuguese) 2022-08-28 15:49:29 +02:00
b2c897660d New translations builder.json (Polish) 2022-08-28 15:49:28 +02:00
c1a7fe7354 New translations builder.json (Dutch) 2022-08-28 15:49:27 +02:00
b628c4a21b New translations builder.json (Italian) 2022-08-28 15:49:26 +02:00
5fb4935146 New translations builder.json (Persian) 2022-08-28 15:49:25 +02:00
ae5280435d New translations builder.json (Hungarian) 2022-08-28 15:49:24 +02:00
6451609d8f New translations builder.json (Finnish) 2022-08-28 15:49:24 +02:00
edfe79f580 New translations builder.json (Greek) 2022-08-28 15:49:23 +02:00
5d7318d46d New translations builder.json (German) 2022-08-28 15:49:22 +02:00
77428c1661 New translations builder.json (Danish) 2022-08-28 15:49:21 +02:00
a2e075df39 New translations builder.json (Czech) 2022-08-28 15:49:20 +02:00
63af1d2b69 New translations builder.json (Arabic) 2022-08-28 15:49:19 +02:00
99c5016762 New translations builder.json (Spanish) 2022-08-28 15:49:18 +02:00
44ff6caf27 New translations builder.json (French) 2022-08-28 15:49:17 +02:00
7d2981f7ce New translations landing.json (Bulgarian) 2022-08-28 15:49:16 +02:00
fcc5dd4bad New translations builder.json (Hebrew) 2022-08-28 15:49:15 +02:00
a9fb995d39 New translations builder.json (Tamil) 2022-08-28 15:49:14 +02:00
31a85bfaa6 New translations builder.json (Hindi) 2022-08-28 15:49:13 +02:00
51151a601e New translations builder.json (Bengali) 2022-08-28 15:49:08 +02:00
9931b22313 New translations builder.json (Odia) 2022-08-28 15:49:04 +02:00
fdf6b76c21 New translations builder.json (Kannada) 2022-08-28 15:49:03 +02:00
b4696301ed New translations builder.json (Malayalam) 2022-08-28 15:49:02 +02:00
294d7b5dab New translations builder.json (Bulgarian) 2022-08-28 15:49:00 +02:00
0430920f56 New translations landing.json (Catalan) 2022-08-28 15:48:59 +02:00
5444b4f5ab New translations landing.json (Romanian) 2022-08-28 15:48:58 +02:00
d649b7fc08 New translations dashboard.json (Marathi) 2022-08-28 15:48:58 +02:00
20b39c0b35 New translations dashboard.json (Korean) 2022-08-28 15:48:56 +02:00
8b87b054ee New translations common.json (Marathi) 2022-08-28 15:48:53 +02:00
5eb68e9e21 New translations landing.json (Japanese) 2022-08-28 15:48:53 +02:00
ec2606d625 New translations common.json (Korean) 2022-08-28 15:48:51 +02:00
9055010f61 New translations builder.json (Marathi) 2022-08-28 15:48:49 +02:00
9763b5c270 New translations builder.json (Ukrainian) 2022-08-28 15:48:48 +02:00
75c3bfe9e5 New translations builder.json (Norwegian) 2022-08-28 15:48:47 +02:00
7f39247655 New translations builder.json (Korean) 2022-08-28 15:48:46 +02:00
d6f11e7807 New translations builder.json (Japanese) 2022-08-28 15:48:45 +02:00
361a1e65d0 New translations builder.json (Catalan) 2022-08-28 15:48:44 +02:00
6fddbe0c59 New translations landing.json (Korean) 2022-08-28 15:48:43 +02:00
3412711f27 New translations landing.json (Serbian (Cyrillic)) 2022-08-28 15:48:42 +02:00
a4bfc17431 New translations landing.json (Khmer) 2022-08-28 15:48:41 +02:00
7c698ef9d2 New translations builder.json (Khmer) 2022-08-28 15:48:40 +02:00
e929faf9b0 New translations builder.json (Turkish) 2022-08-28 15:48:39 +02:00
e3ff18b6dd New translations landing.json (Nepali) 2022-08-28 15:48:37 +02:00
2734493ca4 New translations landing.json (Norwegian) 2022-08-28 15:48:36 +02:00
f0015143c6 New translations builder.json (Nepali) 2022-08-28 15:48:35 +02:00
8d97b195a0 New translations modals.json (Korean) 2022-08-28 15:48:33 +02:00
f30692196a New translations landing.json (Marathi) 2022-08-28 15:48:31 +02:00
242278edd1 New translations landing.json (Ukrainian) 2022-08-28 15:48:30 +02:00
162759c716 New translations modals.json (Marathi) 2022-08-28 15:48:29 +02:00
f0c6bd16f5 New translations builder.json (Romanian) 2022-08-28 15:48:28 +02:00
fac8a9d4ff fix ul > li styles, add docs link to pages 2022-08-28 15:38:52 +02:00
9ff1ffb0b9 Merge pull request #988 from AmruthPillai/feature/remove-docs
Feature Release: v3.6.3
2022-08-28 11:51:08 +02:00
79d3ef1306 docs(docs): 🗑️ remove docs app, include more i18n locales 2022-08-28 11:16:08 +02:00
f4a12285f5 Merge branch 'main' of github.com:AmruthPillai/Reactive-Resume 2022-08-28 10:57:49 +02:00
120ad827ad Merge pull request #986 from AmruthPillai/i18n_main
New Crowdin updates
2022-08-28 10:57:40 +02:00
a129b2033f New translations builder.json (Bengali) 2022-08-28 10:56:29 +02:00
372e508936 New translations builder.json (Hindi) 2022-08-28 10:56:28 +02:00
ce8ada2621 New translations builder.json (Malayalam) 2022-08-28 10:56:27 +02:00
d0563d2ec9 New translations builder.json (Kannada) 2022-08-28 10:56:26 +02:00
dacd4e311c New translations builder.json (Odia) 2022-08-28 10:56:25 +02:00
d6d016ba5d New translations builder.json (Finnish) 2022-08-28 10:56:12 +02:00
407ac990ac New translations builder.json (French) 2022-08-28 10:56:12 +02:00
895e9845fc New translations builder.json (Spanish) 2022-08-28 10:56:11 +02:00
859a44197d New translations builder.json (Arabic) 2022-08-28 10:56:10 +02:00
0b80f33d46 New translations builder.json (Czech) 2022-08-28 10:56:09 +02:00
f246a17038 New translations builder.json (Danish) 2022-08-28 10:56:08 +02:00
10c13d54be New translations builder.json (German) 2022-08-28 10:56:07 +02:00
66316b740b New translations builder.json (Greek) 2022-08-28 10:56:06 +02:00
ae94748abe New translations builder.json (Hebrew) 2022-08-28 10:56:05 +02:00
fe11be60d3 New translations builder.json (Portuguese) 2022-08-28 10:56:04 +02:00
1d3e47adb2 New translations builder.json (Italian) 2022-08-28 10:56:03 +02:00
fdd5f373c4 New translations builder.json (Dutch) 2022-08-28 10:56:02 +02:00
0f99d6cdfb New translations builder.json (Polish) 2022-08-28 10:56:01 +02:00
742865a66a New translations builder.json (Russian) 2022-08-28 10:56:00 +02:00
12dcf04981 New translations builder.json (Swedish) 2022-08-28 10:55:58 +02:00
c0d76eaf0e New translations builder.json (Chinese Simplified) 2022-08-28 10:55:57 +02:00
2f430a1d07 New translations builder.json (Vietnamese) 2022-08-28 10:55:57 +02:00
576b942027 New translations builder.json (Indonesian) 2022-08-28 10:55:56 +02:00
7df777ad0c New translations builder.json (Persian) 2022-08-28 10:55:55 +02:00
e5e30f290a New translations builder.json (Hungarian) 2022-08-28 10:55:54 +02:00
dcb476c28b New translations builder.json (Tamil) 2022-08-28 10:55:53 +02:00
e09f281461 New translations landing.json (Norwegian) 2022-08-28 10:55:52 +02:00
293f008f0a New translations landing.json (Japanese) 2022-08-28 10:55:51 +02:00
f9cd1c779f New translations landing.json (Catalan) 2022-08-28 10:55:51 +02:00
d931590374 New translations landing.json (Romanian) 2022-08-28 10:55:50 +02:00
907ffacca0 New translations dashboard.json (Ukrainian) 2022-08-28 10:55:49 +02:00
a263d54319 New translations dashboard.json (Serbian (Cyrillic)) 2022-08-28 10:55:48 +02:00
0d478e1286 New translations dashboard.json (Japanese) 2022-08-28 10:55:47 +02:00
08997a1728 New translations dashboard.json (Catalan) 2022-08-28 10:55:46 +02:00
688bb11844 New translations common.json (Ukrainian) 2022-08-28 10:55:45 +02:00
0bf4e0b2ae New translations common.json (Serbian (Cyrillic)) 2022-08-28 10:55:44 +02:00
60bbfb6703 New translations common.json (Norwegian) 2022-08-28 10:55:43 +02:00
706307b073 New translations common.json (Japanese) 2022-08-28 10:55:42 +02:00
3be18636ff New translations common.json (Catalan) 2022-08-28 10:55:42 +02:00
b2ee2f9d09 New translations common.json (Romanian) 2022-08-28 10:55:41 +02:00
fe54a2388e New translations dashboard.json (Romanian) 2022-08-28 10:55:40 +02:00
be170dd985 New translations landing.json (Ukrainian) 2022-08-28 10:55:39 +02:00
7fd26ad2c3 New translations landing.json (Serbian (Cyrillic)) 2022-08-28 10:55:38 +02:00
ec30aff4d1 New translations modals.json (Romanian) 2022-08-28 10:55:37 +02:00
0b3023989b New translations modals.json (Khmer) 2022-08-28 10:55:37 +02:00
3b96348183 New translations modals.json (Nepali) 2022-08-28 10:55:34 +02:00
30080b23cd New translations landing.json (Nepali) 2022-08-28 10:55:33 +02:00
b3ba1e5b56 New translations dashboard.json (Nepali) 2022-08-28 10:55:32 +02:00
bf72b557ca New translations builder.json (Nepali) 2022-08-28 10:55:31 +02:00
344fcb1078 New translations common.json (Nepali) 2022-08-28 10:55:30 +02:00
ddd71567c1 New translations modals.json (Ukrainian) 2022-08-28 10:55:29 +02:00
adc679a6e5 New translations modals.json (Serbian (Cyrillic)) 2022-08-28 10:55:29 +02:00
8f49536119 New translations modals.json (Norwegian) 2022-08-28 10:55:28 +02:00
750fedbd74 New translations modals.json (Japanese) 2022-08-28 10:55:27 +02:00
cd59ea7e9b New translations modals.json (Catalan) 2022-08-28 10:55:26 +02:00
5c1b44ddea New translations builder.json (Japanese) 2022-08-28 10:55:25 +02:00
eb6450a9de New translations builder.json (Norwegian) 2022-08-28 10:55:24 +02:00
0b620f41fc New translations builder.json (Ukrainian) 2022-08-28 10:55:24 +02:00
64e0e677d7 New translations builder.json (Bulgarian) 2022-08-28 10:55:23 +02:00
19ae1cf036 New translations builder.json (Turkish) 2022-08-28 10:55:22 +02:00
c221cef77f New translations builder.json (Khmer) 2022-08-28 10:55:21 +02:00
77e3dc2b16 New translations builder.json (Catalan) 2022-08-28 10:55:20 +02:00
9c9368acd5 New translations builder.json (Romanian) 2022-08-28 10:55:19 +02:00
22b91d3f94 feat(docker): add arm64 support 2022-08-28 09:57:15 +02:00
d844092d0f fix(client): 🎨 add style to make list item appear after bullet icon 2022-08-28 09:57:00 +02:00
b3e118fb8b New translations builder.json (Serbian (Cyrillic)) 2022-08-27 12:11:42 +02:00
fe37eb2791 fix(client): 💄 add overflow-y-scroll to left/right sidebar navigation 2022-08-26 08:06:47 +02:00
7902f67f4f feat: update app version to 3.6.2 2022-08-26 00:00:18 +02:00
57dd110187 Merge pull request #981 from AmruthPillai/i18n_main
New Crowdin updates
2022-08-25 10:06:11 +02:00
829375e87a New translations landing.json (Khmer) 2022-08-24 14:27:42 +02:00
0a15b4ebc9 New translations dashboard.json (Khmer) 2022-08-24 14:27:41 +02:00
2bff3fc20b New translations common.json (Khmer) 2022-08-24 14:27:40 +02:00
1e997fe67c bump up versions to v3.6.1 2022-08-23 08:04:25 +02:00
dbf06455e4 Merge pull request #980 from AmruthPillai/i18n_main
New Crowdin updates
2022-08-22 20:44:32 +02:00
42c7c9ade1 New translations modals.json (Odia) 2022-08-22 20:15:54 +02:00
36c19bac3f New translations modals.json (Kannada) 2022-08-22 20:15:53 +02:00
44a9300aff New translations modals.json (Malayalam) 2022-08-22 20:15:52 +02:00
610b5ba9d4 New translations modals.json (Hindi) 2022-08-22 20:15:51 +02:00
769e8811cd New translations modals.json (Bengali) 2022-08-22 20:15:50 +02:00
676fbcafe7 New translations modals.json (Tamil) 2022-08-22 20:15:49 +02:00
3935ae1e04 New translations modals.json (Indonesian) 2022-08-22 20:15:41 +02:00
ef6b765266 New translations modals.json (Persian) 2022-08-22 20:15:40 +02:00
647dd6e682 New translations modals.json (Vietnamese) 2022-08-22 20:15:39 +02:00
43841e9962 New translations modals.json (Chinese Simplified) 2022-08-22 20:15:38 +02:00
e2236c3207 New translations modals.json (German) 2022-08-22 20:15:37 +02:00
7389d33ee5 New translations modals.json (Greek) 2022-08-22 20:15:25 +02:00
4b21eabec9 New translations modals.json (Dutch) 2022-08-22 20:15:24 +02:00
1815b0fa21 New translations modals.json (Hebrew) 2022-08-22 20:15:23 +02:00
6c4d3cbd56 New translations modals.json (Finnish) 2022-08-22 20:15:22 +02:00
8c2f3c8504 New translations modals.json (Turkish) 2022-08-22 20:15:21 +02:00
3aa7a98d9d New translations modals.json (Swedish) 2022-08-22 20:15:20 +02:00
5519ec898d New translations modals.json (Russian) 2022-08-22 20:15:19 +02:00
1cd4c5d733 New translations modals.json (Portuguese) 2022-08-22 20:15:18 +02:00
73d11c323f New translations modals.json (Polish) 2022-08-22 20:15:17 +02:00
38812fcf25 New translations modals.json (French) 2022-08-22 20:15:16 +02:00
c22de12f12 New translations modals.json (Spanish) 2022-08-22 20:15:15 +02:00
c94c971599 New translations modals.json (Arabic) 2022-08-22 20:15:13 +02:00
c9a71a5917 New translations modals.json (Czech) 2022-08-22 20:15:12 +02:00
8a29387470 New translations modals.json (Danish) 2022-08-22 20:15:11 +02:00
592511b090 New translations modals.json (Hungarian) 2022-08-22 20:15:10 +02:00
af63fd38d4 New translations modals.json (Italian) 2022-08-22 20:15:09 +02:00
bf38b1b254 New translations modals.json (Bulgarian) 2022-08-22 20:14:23 +02:00
4a1c0079db Merge pull request #979 from AmruthPillai/feature/turbo
Implement Turbo Workspaces, add ARM64 support, fix Google OAuth etc.
2022-08-22 19:59:43 +02:00
5b6f6b7621 use nodemailer/smtp instead of sendgrid 2022-08-22 19:26:13 +02:00
02587255fe update version to 3.6.0 2022-08-22 15:24:30 +02:00
9ef2a84ac2 update examples for reaching client/server in .env 2022-08-22 12:44:50 +02:00
77b1c5b536 update Dockerfile 2022-08-22 12:17:41 +02:00
bf956fe18c use @react-oauth/google library for google auth 2022-08-22 11:26:30 +02:00
4114f1e1dd remove timeouts in CI 2022-08-22 09:34:35 +02:00
668d39fa87 change tagname of docker image 2022-08-22 09:17:32 +02:00
0d88a18757 remove husky, lint-staged 2022-08-21 22:18:27 +02:00
0630369087 Implement Turbo Workspaces, among other things 2022-08-21 22:18:12 +02:00
73af4a6859 chore(dependencies): updating dependencies to latest versions 2022-08-21 00:44:11 +02:00
99ddeb25a9 Merge pull request #972 from AmruthPillai/i18n_main
New Crowdin updates
2022-08-17 08:46:38 +02:00
685aa06778 Merge pull request #974 from kgotso/main
Removed Check on hard coded urls
2022-08-15 22:57:01 +02:00
460abc6f1d Removed Check on hard coded urls
This forces the backend to continuously call home and break if no response is received
2022-08-15 19:43:32 +02:00
04f02157ac New translations builder.json (Turkish) 2022-08-14 21:41:45 +02:00
828a4a8715 Merge pull request #970 from m-GDEV/patch-1
Fixed small formatting issue in README
2022-08-13 09:23:43 +02:00
5b3141cd49 Fixed small formatting issue in README 2022-08-12 17:06:55 -04:00
779d22101f chore(release): 3.5.3 2022-08-11 20:21:55 +02:00
ef240b2110 add Bulgarian language, update dependencies 2022-08-11 20:21:19 +02:00
32bb7354a4 Merge pull request #969 from AmruthPillai/i18n_main
New Crowdin updates
2022-08-11 20:12:06 +02:00
0dcbad1f8a New translations modals.json (Bulgarian) 2022-08-11 10:27:23 +02:00
a74921b27a New translations builder.json (Bulgarian) 2022-08-11 10:27:21 +02:00
d4f47423c9 New translations common.json (Bulgarian) 2022-08-11 10:27:20 +02:00
03f9a6543c New translations dashboard.json (Bulgarian) 2022-08-11 10:27:18 +02:00
eb89cfcf5d New translations landing.json (Bulgarian) 2022-08-11 10:27:17 +02:00
c52ef9ecb7 Merge pull request #965 from AmruthPillai/dependabot/github_actions/docker/build-push-action-3.1.1
chore(deps): bump docker/build-push-action from 3.1.0 to 3.1.1
2022-08-08 05:53:47 +02:00
c499abbb88 chore(deps): bump docker/build-push-action from 3.1.0 to 3.1.1
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 02:15:50 +00:00
1a7ee88ecd chore(release): 3.5.2 2022-08-04 16:15:29 +02:00
16d19eb70f feat(client): 💫 add Finnish language support 2022-08-04 16:13:49 +02:00
331346b99c chore(dependencies): ⬆️ upgrading dependencies to latest versions 2022-08-04 16:10:33 +02:00
95d265f672 Merge pull request #956 from AmruthPillai/i18n_main
New Crowdin updates
2022-08-04 16:09:46 +02:00
315c7d6328 New translations modals.json (Finnish) 2022-07-31 22:22:32 +02:00
490e174564 New translations common.json (Finnish) 2022-07-31 22:22:30 +02:00
b5cde79f8b New translations builder.json (Finnish) 2022-07-31 22:22:29 +02:00
d50f14bb78 New translations dashboard.json (Finnish) 2022-07-31 22:22:28 +02:00
c13a751c1a New translations landing.json (Finnish) 2022-07-31 22:22:26 +02:00
5c37fc55d5 New translations builder.json (Indonesian) 2022-07-30 17:08:34 +02:00
48a0f90597 chore(release): 3.5.1 2022-07-30 13:01:00 +02:00
05d3f1f06f fix(server): don't initialize sendgrid if the apikey is empty 2022-07-30 12:57:35 +02:00
4d43f6a642 feat(client): ask for confirmation when resetting a resume 2022-07-30 12:56:40 +02:00
f7363ccdd7 Merge branch 'main' of github.com:AmruthPillai/Reactive-Resume 2022-07-30 12:56:13 +02:00
07c91e9ac2 feat(docker): remove ports from postgres docker instance 2022-07-30 12:56:04 +02:00
cbe08f1d2c Merge pull request #950 from AmruthPillai/dependabot/github_actions/docker/build-push-action-3.1.0
chore(deps): bump docker/build-push-action from 3.0.0 to 3.1.0
2022-07-30 12:43:46 +02:00
c2617a8277 Merge pull request #944 from AmruthPillai/i18n_main
New Crowdin updates
2022-07-30 12:43:36 +02:00
fe72d2de41 chore(release): 3.5.0 2022-07-30 12:42:31 +02:00
23667e218f chore(deps): updating project dependencies to their latest versions 2022-07-30 12:41:37 +02:00
977fa72dde fix(client): 🐛 fix mui rendering of utc dates 2022-07-30 12:21:05 +02:00
5197f954c0 fix(client): 🐛 attempt to fix the one-off date issue
use utc functions from dayjs to correspond to the same date on the server
2022-07-31 02:13:08 -08:00
58341e4cd2 New translations builder.json (Serbian (Cyrillic)) 2022-07-28 13:44:38 +02:00
1559703567 chore(deps): bump docker/build-push-action from 3.0.0 to 3.1.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3.0.0...v3.1.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 02:24:03 +00:00
0a1fd50d07 New translations dashboard.json (Norwegian) 2022-07-17 03:00:38 +02:00
1c19062c63 chore(release): 3.4.8 2022-07-13 11:08:14 +02:00
25cf594eb9 feat(google): add toast to display error message from google 2022-07-13 11:05:27 +02:00
1c3beee6cd chore(deps): update dependencies 2022-07-13 09:40:29 +02:00
95c3d4c315 Merge pull request #937 from AmruthPillai/dependabot/gradle/app/org.jetbrains.kotlin.android-1.7.10
chore(deps): bump org.jetbrains.kotlin.android from 1.7.0 to 1.7.10 in /app
2022-07-12 15:33:31 +02:00
85df339e56 chore(deps): bump org.jetbrains.kotlin.android in /app
Bumps [org.jetbrains.kotlin.android](https://github.com/JetBrains/kotlin) from 1.7.0 to 1.7.10.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.0...v1.7.10)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin.android
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 02:40:56 +00:00
d61ad44ebc chore(release): 3.4.7 2022-07-01 01:04:52 +02:00
ccb1eff749 chore(mui): migrate from mui/lab to mui/x-date-pickers 2022-07-01 01:04:03 +02:00
bfb48e3aa7 fix(mui): update mui datepickers to newer package 2022-07-01 01:01:27 +02:00
e2e08ad390 Merge branch 'main' of github.com:AmruthPillai/Reactive-Resume 2022-07-01 00:50:17 +02:00
f0dda06af3 Merge pull request #932 from AmruthPillai/i18n_main
New Crowdin updates
2022-07-01 00:50:10 +02:00
4c4e77e21d New translations common.json (Portuguese) 2022-07-01 00:48:52 +02:00
f364ae8929 New translations common.json (Indonesian) 2022-07-01 00:48:49 +02:00
b52f292d89 New translations dashboard.json (Indonesian) 2022-07-01 00:48:32 +02:00
8cac7f907c New translations modals.json (Hebrew) 2022-07-01 00:48:25 +02:00
a18a60679f New translations builder.json (Hebrew) 2022-07-01 00:48:04 +02:00
5cc6a81b8c New translations landing.json (Hebrew) 2022-07-01 00:48:02 +02:00
6ff212b698 New translations dashboard.json (Hebrew) 2022-07-01 00:48:00 +02:00
56bcec5196 chore(deps): update dependencies across all projects 2022-07-01 00:46:41 +02:00
12019f90e9 Merge pull request #928 from ravindra3003/main
UpdateTutorial
2022-07-01 00:27:29 +02:00
7e6e69ed49 Update create-resume.mdx 2022-06-23 13:14:16 +05:30
a09a945e17 Update create-account.mdx 2022-06-23 13:12:21 +05:30
df714dc8de Update create-account.mdx 2022-06-22 15:47:01 +05:30
28b63ef0c7 Update create-account.mdx 2022-06-22 15:16:45 +05:30
1b594dac61 Update create-resume.mdx 2022-06-22 15:00:18 +05:30
dd34a30ee0 Update create-account.mdx 2022-06-22 12:09:18 +05:30
0af398ceed Update create-account.mdx 2022-06-22 11:45:45 +05:30
04abd2cacc Update create-account.mdx 2022-06-22 11:37:15 +05:30
a037a091e7 chore(release): 3.4.6 2022-06-19 20:55:23 +02:00
f3a4c17cb4 correct versions 2022-06-19 20:55:14 +02:00
f06f7ad2e5 chore(release): 3.6.2 2022-06-19 20:52:34 +02:00
aab2e5c8a9 correct versions 2022-06-19 20:52:24 +02:00
4318dbe762 add languages 2022-06-19 20:51:10 +02:00
ae3ff274ee updates to app 2022-06-19 20:44:28 +02:00
164403c495 chore(release): 3.4.6 2022-06-19 20:44:04 +02:00
8595c92fb7 Merge pull request #906 from dvd741-a/main
Add File based Storage toggle for Photos
2022-06-18 16:53:05 +02:00
8f75f32f88 Merge pull request #903 from AmruthPillai/i18n_main
New Crowdin updates
2022-06-18 16:52:54 +02:00
0d44189a5f Merge branch 'main' into i18n_main 2022-06-18 16:51:51 +02:00
cd16a6d360 Merge pull request #902 from Mhnramin/main
New translation for Bahasa (Indonesia)
2022-06-18 16:49:25 +02:00
7b795bfaa4 Merge pull request #914 from AmruthPillai/dependabot/gradle/app/org.jetbrains.kotlin.android-1.7.0
chore(deps): bump org.jetbrains.kotlin.android from 1.6.21 to 1.7.0 in /app
2022-06-18 16:49:08 +02:00
8f78d47661 Change Dockerfile to include Volume 2022-06-18 14:21:10 +02:00
0b5e5a2ece New translations common.json (Hebrew) 2022-06-14 03:09:35 +05:30
9eade9514c chore(deps): bump org.jetbrains.kotlin.android in /app
Bumps [org.jetbrains.kotlin.android](https://github.com/JetBrains/kotlin) from 1.6.21 to 1.7.0.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.7.0/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.6.21...v1.7.0)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin.android
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 02:22:25 +00:00
d744e06e96 New translations builder.json (Persian) 2022-06-07 23:23:40 +05:30
9657c199d2 New translations common.json (Persian) 2022-06-07 23:23:39 +05:30
2dbe737b73 New translations dashboard.json (Persian) 2022-06-07 23:23:38 +05:30
f624699efa New translations landing.json (Persian) 2022-06-07 23:23:37 +05:30
e46f473754 New translations modals.json (Persian) 2022-06-07 23:23:36 +05:30
767f4bf4bc Correction 2022-06-06 15:41:08 +02:00
1c5d025c15 Version 2022-06-06 15:26:37 +02:00
8de8d89290 File Storage toggle 2022-06-06 15:15:39 +02:00
83662122a5 Changes 2022-06-06 02:31:44 +02:00
126482a760 chore(release): 3.6.1 2022-06-06 01:36:29 +02:00
b04c22a27b Changes 2022-06-06 01:35:46 +02:00
63f88a3d1c Changes 2022-06-06 01:34:58 +02:00
bd519db14f chore(release): 3.6.0 2022-06-06 01:32:56 +02:00
a49aa42176 New translations modals.json (Indonesian) 2022-06-05 12:49:38 +05:30
1a382db4d9 New translations builder.json (Indonesian) 2022-06-05 12:49:36 +05:30
c68f75dc8c New translations common.json (Indonesian) 2022-06-05 12:49:35 +05:30
c12de0c013 New translations dashboard.json (Indonesian) 2022-06-05 12:49:34 +05:30
4cafaf306a New translations landing.json (Indonesian) 2022-06-05 12:49:33 +05:30
0238cf18a5 New translation for Bahasa (Indonesia) 2022-06-05 08:16:49 +08:00
2f6072a7ba Merge pull request #889 from AmruthPillai/i18n_main
New Crowdin updates
2022-05-24 08:25:16 +05:30
55dd2c5925 Merge pull request #879 from AmruthPillai/dependabot/github_actions/docker/build-push-action-3.0.0
chore(deps): bump docker/build-push-action from 2.10.0 to 3.0.0
2022-05-24 08:25:05 +05:30
a3e25f87fa Merge pull request #878 from AmruthPillai/dependabot/github_actions/docker/login-action-2.0.0
chore(deps): bump docker/login-action from 1.14.1 to 2.0.0
2022-05-24 08:24:56 +05:30
9e82ea11c3 chore(release): 3.4.5 2022-05-24 08:23:03 +05:30
62fd63e41f fix(i18n): fix language mismatch in exported pdf 2022-05-24 08:21:03 +05:30
b91c175352 New translations builder.json (Arabic) 2022-05-18 19:51:52 +05:30
898e2314fc New translations builder.json (Arabic) 2022-05-18 18:39:53 +05:30
bca2aa2fe5 chore(deps): bump docker/build-push-action from 2.10.0 to 3.0.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2.10.0 to 3.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2.10.0...v3.0.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 02:51:05 +00:00
427fdb717a chore(deps): bump docker/login-action from 1.14.1 to 2.0.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 1.14.1 to 2.0.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1.14.1...v2.0.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 02:51:02 +00:00
ee5b0187e2 docs(i18n): add Hungarian language to docs readme 2022-05-02 09:01:50 +02:00
94d05f33b4 chore(release): v3.4.4 2022-05-02 08:59:36 +02:00
35fe4e2774 feat(i18n): add Hungrarian (Magyar) language 2022-05-02 08:58:25 +02:00
317901a4d2 Merge pull request #870 from AmruthPillai/i18n_main
New Crowdin updates
2022-05-02 08:50:01 +02:00
350ffcbc43 New translations builder.json (Odia) 2022-05-02 08:47:55 +02:00
2c074a96c8 New translations builder.json (Kannada) 2022-05-02 08:47:54 +02:00
79f140b2d0 New translations builder.json (Malayalam) 2022-05-02 08:47:53 +02:00
649c655ad5 New translations builder.json (Hindi) 2022-05-02 08:47:52 +02:00
d5284a90d1 New translations builder.json (Bengali) 2022-05-02 08:47:51 +02:00
bd18c53ab8 New translations builder.json (Tamil) 2022-05-02 08:47:50 +02:00
704c1ab7d4 New translations builder.json (Vietnamese) 2022-05-02 08:47:35 +02:00
1dbd7f221e New translations builder.json (Chinese Simplified) 2022-05-02 08:47:34 +02:00
e1a47ffbe2 New translations modals.json (Hungarian) 2022-05-02 08:47:33 +02:00
2add629970 New translations modals.json (Czech) 2022-05-02 08:47:31 +02:00
a48fcd9c97 New translations landing.json (Hungarian) 2022-05-02 08:47:29 +02:00
df7b00cb2c New translations builder.json (Turkish) 2022-05-02 08:47:28 +02:00
27fc939101 New translations builder.json (Portuguese) 2022-05-02 08:47:26 +02:00
7c574d17e4 New translations builder.json (Polish) 2022-05-02 08:47:25 +02:00
86a105f5a5 New translations builder.json (Dutch) 2022-05-02 08:47:25 +02:00
327bcc2b32 New translations builder.json (Italian) 2022-05-02 08:47:24 +02:00
a6cbd85010 New translations builder.json (Greek) 2022-05-02 08:47:23 +02:00
371b820923 New translations builder.json (German) 2022-05-02 08:47:22 +02:00
1d47fd0267 New translations builder.json (Danish) 2022-05-02 08:47:21 +02:00
276fc95bb0 New translations builder.json (Czech) 2022-05-02 08:47:20 +02:00
34c8861321 New translations builder.json (Arabic) 2022-05-02 08:47:19 +02:00
780b782579 New translations builder.json (French) 2022-05-02 08:47:18 +02:00
9daa99fd5b New translations builder.json (Spanish) 2022-05-02 08:47:16 +02:00
76b3aa29cf New translations landing.json (Czech) 2022-05-02 08:47:16 +02:00
25d4913fab New translations common.json (Hungarian) 2022-05-02 08:47:15 +02:00
0efeff3a4f New translations common.json (Czech) 2022-05-02 08:47:13 +02:00
f56089925e New translations builder.json (Swedish) 2022-05-02 08:47:12 +02:00
5afae08f20 New translations builder.json (Hungarian) 2022-05-02 08:47:11 +02:00
4bf114dfd6 New translations dashboard.json (Hungarian) 2022-05-02 08:47:09 +02:00
23a3c2e624 New translations dashboard.json (Czech) 2022-05-02 08:47:07 +02:00
71862f4354 New translations builder.json (Russian) 2022-05-01 15:42:24 +02:00
6861c0f0fa chore(release): 3.4.3 2022-05-01 08:03:37 +02:00
9a18e74b90 revert(react): downgrade back to 17.0.2 due to lack of support 2022-05-01 08:03:22 +02:00
4dd1b70079 remove linux/arm64 builds, failing temporarily 2022-04-30 13:39:23 +02:00
326 changed files with 13891 additions and 11177 deletions

View File

@ -1,5 +0,0 @@
ARG VARIANT="lts-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm

View File

@ -1,27 +0,0 @@
{
"name": "Node.js",
"build": {
"dockerfile": "Dockerfile",
"args": { "VARIANT": "16-bullseye" }
},
// Set *default* container specific settings.json values on container create.
"settings": {},
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "lokalise.i18n-ally"],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [80, 5432],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pnpm install",
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "node",
"features": {
"docker-from-docker": "latest"
}
}

View File

@ -1,13 +1,22 @@
# Android App
/app
# Build Artifacts
dist
.next
.turbo
# IDEs
.vscode
# Project Metadata
.crowdin.yml
# Documentation
README.md
SECURITY.md
CHANGELOG.md
CODE_OF_CONDUCT.md
# Project Dependencies
node_modules
@ -16,6 +25,3 @@ node_modules
Dockerfile
.dockerignore
docker-compose.yml
# Android App
/app

View File

@ -1,7 +1,11 @@
# Turbo Cache (Optional)
TURBO_TEAM=
TURBO_TOKEN=
# Server + Client
TZ=UTC
PUBLIC_URL=http://localhost:3000
PUBLIC_SERVER_URL=http://localhost:3000/api
PUBLIC_SERVER_URL=http://localhost:3100
PUBLIC_GOOGLE_CLIENT_ID=
# Server + Database
@ -18,10 +22,12 @@ JWT_SECRET=
JWT_EXPIRY_TIME=604800
GOOGLE_CLIENT_SECRET=
GOOGLE_API_KEY=
SENDGRID_API_KEY=
SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID=
SENDGRID_FROM_NAME=
SENDGRID_FROM_EMAIL=
MAIL_FROM_NAME=
MAIL_FROM_EMAIL=
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=
MAIL_PASSWORD=
STORAGE_BUCKET=
STORAGE_REGION=
STORAGE_ENDPOINT=

View File

@ -1,31 +1,22 @@
{
"root": true,
"ignorePatterns": ["/app"],
"parser": "@typescript-eslint/parser",
"extends": ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort", "unused-imports"],
"extends": ["plugin:@typescript-eslint/recommended"],
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort"],
"rules": {
// ESLint
"no-unused-vars": "off",
// Simple Import Sort
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
// TypeScript ESLint
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
// Simple Import Sort
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
// Unused Imports
"no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
"vars": "all",
"varsIgnorePattern": "^_",
"args": "none",
"argsIgnorePattern": "^_"
}
]
"@typescript-eslint/explicit-module-boundary-types": "off"
},
"overrides": [
{

1
.github/FUNDING.yml vendored
View File

@ -1 +1,2 @@
github: AmruthPillai
custom: https://paypal.me/RajaRajanA

View File

@ -1,36 +1,43 @@
---
name: Bug Report
about: Create a report to help improve
title: "[BUG] "
title: '[BUG] '
labels: bug
assignees: ''
---
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**Product Flavor**
- [ ] Managed (https://rxresu.me)
- [ ] Self Hosted
**To Reproduce**
<!-- Steps to reproduce the behavior: -->
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
**Desktop (please complete the following information):**
- OS: <!--[e.g. iOS]-->
- Browser <!--[e.g. chrome, safari]-->
- Version <!--[e.g. 22]-->
**Additional context**
<!-- Add any other context about the problem here. -->

View File

@ -1,20 +1,23 @@
---
name: Feature Request
about: Suggest an idea for this project
title: "[FEATURE] "
title: '[FEATURE] '
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

View File

@ -9,35 +9,44 @@ jobs:
name: Client
runs-on: ubuntu-latest
env:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.0.2
with:
fetch-depth: 2
- id: version
name: Get Version
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
uses: docker/setup-qemu-action@v2.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.6.0
- id: buildx
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.0.0
with:
install: true
- name: Login to Docker
uses: docker/login-action@v1.14.1
- name: Login to Docker Hub
uses: docker/login-action@v2.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.14.1
uses: docker/login-action@v2.0.0
with:
registry: ghcr.io
username: $GITHUB_REPOSITORY_OWNER
password: ${{ secrets.GH_TOKEN }}
- name: Build and Push Client Image
uses: docker/build-push-action@v2.10.0
uses: docker/build-push-action@v3.1.1
with:
context: .
push: true
@ -53,40 +62,49 @@ jobs:
name: Server
runs-on: ubuntu-latest
env:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.0.2
with:
fetch-depth: 2
- id: version
name: Get Version
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
uses: docker/setup-qemu-action@v2.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.6.0
- id: buildx
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.0.0
with:
install: true
- name: Login to Docker
uses: docker/login-action@v1.14.1
- name: Login to Docker Hub
uses: docker/login-action@v2.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.14.1
uses: docker/login-action@v2.0.0
with:
registry: ghcr.io
username: $GITHUB_REPOSITORY_OWNER
password: ${{ secrets.GH_TOKEN }}
- name: Build and Push Server Image
uses: docker/build-push-action@v2.10.0
uses: docker/build-push-action@v3.1.1
with:
context: .
push: true
file: server/Dockerfile
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
tags: |
amruthpillai/reactive-resume:server-latest
amruthpillai/reactive-resume:server-${{ steps.version.outputs.tag }}

84
.github/workflows/docker-build.yml vendored Normal file
View File

@ -0,0 +1,84 @@
name: Build Docker Image
on: pull_request
jobs:
client:
name: Client
runs-on: ubuntu-latest
env:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.0.2
with:
fetch-depth: 2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2.0.0
- id: buildx
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.0.0
with:
install: true
- id: variables
name: Get Short SHA
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Build Client Image
uses: docker/build-push-action@v3.1.1
with:
context: .
push: false
file: client/Dockerfile
platforms: linux/amd64,linux/arm64
tags: |
amruthpillai/reactive-resume:client-latest
amruthpillai/reactive-resume:client-${{ steps.variables.outputs.sha_short }}
ghcr.io/amruthpillai/reactive-resume:client-latest
ghcr.io/amruthpillai/reactive-resume:client-${{ steps.variables.outputs.sha_short }}
server:
name: Server
runs-on: ubuntu-latest
env:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.0.2
with:
fetch-depth: 2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2.0.0
- id: buildx
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.0.0
with:
install: true
- id: variables
name: Get Short SHA
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Build Server Image
uses: docker/build-push-action@v3.1.1
with:
context: .
push: false
file: server/Dockerfile
platforms: linux/amd64,linux/arm64
tags: |
amruthpillai/reactive-resume:server-latest
amruthpillai/reactive-resume:server-${{ steps.variables.outputs.sha_short }}
ghcr.io/amruthpillai/reactive-resume:server-latest
ghcr.io/amruthpillai/reactive-resume:server-${{ steps.variables.outputs.sha_short }}

3
.gitignore vendored
View File

@ -8,3 +8,6 @@ node_modules
# macOS
.DS_Store
# Turbo
.turbo

View File

@ -1,6 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
pnpm install
pnpm run lint
pnpm run format

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
auto-install-peers=true
strict-peer-dependencies=false

View File

@ -1,3 +1,6 @@
# Android App
/app
# Schema
schema/dist
@ -18,15 +21,9 @@ CHANGELOG.md
# Project Dependencies
node_modules
pnpm-lock.yaml
# Docker
Dockerfile
.dockerignore
docker-compose.yml
# Android App
/app
# Docs
docs/build
docs/.docusaurus

View File

@ -1,3 +1,7 @@
{
"recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "lokalise.i18n-ally"]
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"lokalise.i18n-ally"
]
}

26
.vscode/launch.json vendored
View File

@ -1,26 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Debug: Server",
"port": 9229,
"restart": true,
"stopOnEntry": false,
"protocol": "inspector"
},
{
"name": "Debug: Client",
"type": "node-terminal",
"request": "launch",
"command": "pnpm run dev:client",
"console": "integratedTerminal",
"serverReadyAction": {
"pattern": "started server on .+, url: (https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}

25
.vscode/settings.json vendored
View File

@ -1,25 +1,22 @@
{
"css.validate": false,
"scss.validate": false,
"editor.wordWrap": "on",
"npm.packageManager": "pnpm",
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.wordWrap": "on",
"eslint.workingDirectories": [
"schema",
"client",
"server"
],
"i18n-ally.enabledFrameworks": [
"react"
],
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": [
"client/public/locales"
],
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
"i18n-ally.sortKeys": true,
"scss.validate": false
"conventionalCommits.scopes": [
"client",
"server",
"docker",
"dependencies"
]
}

View File

@ -1,234 +0,0 @@
# Changelog
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.4.2](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.1...v3.4.2) (2022-04-30)
### [3.4.1](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.0...v3.4.1) (2022-04-30)
### Bug Fixes
* **typeorm:** update typeorm to latest 0.2.x for secpatch ([5bdb92b](https://github.com/AmruthPillai/Reactive-Resume/commit/5bdb92b1cff9e56879f9bbf31801d6554a00a8d5))
### [3.4.0](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.3...v3.4.0) (2022-04-30)
### [3.3.4](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.3...v3.3.4) (2022-04-09)
### [3.3.3](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.2...v3.3.3) (2022-04-09)
### Features
* **profile:** add XING profile icon ([1e59f73](https://github.com/AmruthPillai/Reactive-Resume/commit/1e59f73f79a91d0264c0d2108906ee89d4eb27f8)), closes [#821](https://github.com/AmruthPillai/Reactive-Resume/issues/821)
* **s3:** implement non-ephemeral storage through S3/DO Spaces ([feb911a](https://github.com/AmruthPillai/Reactive-Resume/commit/feb911aea06bacf58ea933d2803a2a89fe36e57b))
### [3.3.2](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.1...v3.3.2) (2022-04-08)
### Bug Fixes
* **types/react:** downgrade to <18 ([fc77b54](https://github.com/AmruthPillai/Reactive-Resume/commit/fc77b548d8d61530b2d158ff83f088bed12d5080))
### [3.3.1](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.3.0...v3.3.1) (2022-04-08)
## [3.3.0](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.11...v3.3.0) (2022-04-08)
### Features
* **upgrade:** changes to code to support new template ([1df7810](https://github.com/AmruthPillai/Reactive-Resume/commit/1df78100ca0667ce9b7834cf2c25384eb21c67c2))
### What's Changed
* New Crowdin updates by @AmruthPillai in https://github.com/AmruthPillai/Reactive-Resume/pull/791
* Bump org.jetbrains.kotlin.android from 1.6.10 to 1.6.20 in /app by @dependabot in https://github.com/AmruthPillai/Reactive-Resume/pull/812
* New Crowdin updates by @AmruthPillai in https://github.com/AmruthPillai/Reactive-Resume/pull/806
* A new template - Leafish by @klejejs in https://github.com/AmruthPillai/Reactive-Resume/pull/811
* Automatic multi-platform Docker image build by @schklom in https://github.com/AmruthPillai/Reactive-Resume/pull/817
### New Contributors
* @klejejs made their first contribution in https://github.com/AmruthPillai/Reactive-Resume/pull/811
* @schklom made their first contribution in https://github.com/AmruthPillai/Reactive-Resume/pull/817
### [3.2.11](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.10...v3.2.11) (2022-03-28)
### [3.2.10](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.9...v3.2.10) (2022-03-24)
### Features
* **i18n:** add portuguese (pt) language to i18n locales ([7f1c82c](https://github.com/AmruthPillai/Reactive-Resume/commit/7f1c82cd9185ebb44486a16132eb44d5c2fb747a))
### [3.2.9](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.8...v3.2.9) (2022-03-21)
### Features
* **i18n:** add nl and ru i18n locales to app ([03cbf22](https://github.com/AmruthPillai/Reactive-Resume/commit/03cbf22c9bee96cac8f228830b67b44529b7ecee))
### [3.2.8](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.7...v3.2.8) (2022-03-18)
### Features
* **client/theme:** add theme switcher to landing page ([8f5632c](https://github.com/AmruthPillai/Reactive-Resume/commit/8f5632c5ad0bc8a4b3028c2806365717fedd78c9))
* **flags:** introduce flags, disable_user_signups ([b6267d0](https://github.com/AmruthPillai/Reactive-Resume/commit/b6267d07ba2dcaed0da3946d136a0a9a01c441d5)), closes [#698](https://github.com/AmruthPillai/Reactive-Resume/issues/698)
* **i18n:** add Vietnamese language to i18n locales ([4390bcc](https://github.com/AmruthPillai/Reactive-Resume/commit/4390bccfb9764f2d2730ec3a124b7befb6792e9a))
### Bug Fixes
* **client/create-rename-slug:** fix slug accepting apostrophes and other special characters ([1facd2a](https://github.com/AmruthPillai/Reactive-Resume/commit/1facd2ad111cd9d990c808b3956d3915e8711acd)), closes [#706](https://github.com/AmruthPillai/Reactive-Resume/issues/706)
* **disable_user_signups:** hide create account link under flag ([80acfe9](https://github.com/AmruthPillai/Reactive-Resume/commit/80acfe97c74bfa05b719285b19144144f3f7c5ba))
### [3.2.7](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.6...v3.2.7) (2022-03-18)
### Features
* **i18n:** add Malayalam (മലയ) language to i18n locales ([3a2e62b](https://github.com/AmruthPillai/Reactive-Resume/commit/3a2e62be4c9acc14f17277c060cc9ea2c417a478))
### Bug Fixes
* **printer/i18n:** fix dates not showing up in resume language when printing ([90321e1](https://github.com/AmruthPillai/Reactive-Resume/commit/90321e1284409ab9442883c04a9b4c591d36f95d)), closes [#729](https://github.com/AmruthPillai/Reactive-Resume/issues/729)
### [3.2.6](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.5...v3.2.6) (2022-03-17)
### Features
* **client/auth/google:** disable google login/registration if GOOGLE_CLIENT_ID is not in ENV ([7f0ee40](https://github.com/AmruthPillai/Reactive-Resume/commit/7f0ee40af4acc7eb41514406ecee3218ace9e891)), closes [#724](https://github.com/AmruthPillai/Reactive-Resume/issues/724)
* **i18n:** add arabic language to i18n locale ([39fa6da](https://github.com/AmruthPillai/Reactive-Resume/commit/39fa6da5dd77ce2e12e81530fa18c2eac722c1f2))
### Bug Fixes
* **i18n:** add missing languages to dayjs date wrapper locales ([9e6dafc](https://github.com/AmruthPillai/Reactive-Resume/commit/9e6dafc8cada5c01559894905996b81004bedaec)), closes [#719](https://github.com/AmruthPillai/Reactive-Resume/issues/719)
* **json-export:** add mimeType and charset to JSON export ([b3ff780](https://github.com/AmruthPillai/Reactive-Resume/commit/b3ff7805cd856a52900d9acef0554867d8ce0b01)), closes [#726](https://github.com/AmruthPillai/Reactive-Resume/issues/726)
* **linkedin:** fix skill modal crashing when importing from linkedin ([a02b85b](https://github.com/AmruthPillai/Reactive-Resume/commit/a02b85b4bb1c4a1499aacddeac7bc59bcb1f7adb)), closes [#718](https://github.com/AmruthPillai/Reactive-Resume/issues/718)
### [3.2.5](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.4...v3.2.5) (2022-03-16)
### Features
* **i18n:** add danish, polish and turkish locales to i18n ([97e9432](https://github.com/AmruthPillai/Reactive-Resume/commit/97e9432d6bd887e666a3443fbfde9a92cef53965))
### Bug Fixes
* **client/templates:** fix text veering off of artboard in most templates ([b2f1fb3](https://github.com/AmruthPillai/Reactive-Resume/commit/b2f1fb3a5502988a49c5cd3e496d9d165f5c1792)), closes [#702](https://github.com/AmruthPillai/Reactive-Resume/issues/702)
### [3.2.4](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.3...v3.2.4) (2022-03-14)
### [3.2.3](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.2...v3.2.3) (2022-03-14)
### Features
* **client/import:** implement import json from reactive resume v2 ([42408ce](https://github.com/AmruthPillai/Reactive-Resume/commit/42408ce8c5ce55904854f9f6e0481889a01edfb8))
### [3.2.2](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.1...v3.2.2) (2022-03-14)
### Bug Fixes
* **client/skills:** make skill level optional ([02e396b](https://github.com/AmruthPillai/Reactive-Resume/commit/02e396bfdbf07ae75661f1e7e4e55060cacee7d0))
### [3.2.1](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.0...v3.2.1) (2022-03-14)
### Features
* **i18n:** add Chinese (Simplified) language to locales ([549363b](https://github.com/AmruthPillai/Reactive-Resume/commit/549363bbe5bdd781699dea9506bd4baedf5740d1))
### Bug Fixes
* **client/basics:** fix issue with overlapping photo filters on safari/webkit/iOS ([e6bda68](https://github.com/AmruthPillai/Reactive-Resume/commit/e6bda688ac3ba1c04e82721add92e755ea5386c3))
* **docker:** fix docker-compose for production grade deployments ([57f7edc](https://github.com/AmruthPillai/Reactive-Resume/commit/57f7edc13432a038c907afc6cb74b5182a9b2333))
## [3.2.0](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.1.4...v3.2.0) (2022-03-14)
### Features
* **i18n:** add Bengali, Italian and other languages ([21931bc](https://github.com/AmruthPillai/Reactive-Resume/commit/21931bc324b5e2440baaaaa2e52a93b4f2c766f8))
### Bug Fixes
* **app:** fix issue with external link redirection in android app ([b18120b](https://github.com/AmruthPillai/Reactive-Resume/commit/b18120b3f7223981e28c0441a6b7725787186edb))
* **client:** fix issue with react-query cache ([ed75a85](https://github.com/AmruthPillai/Reactive-Resume/commit/ed75a858279047dfd43152e041c1a09a625417f5))
### [3.1.4](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.1.3...v3.1.4) (2022-03-12)
### Bug Fixes
* **client:** exported pdf did not contain "Present" keyword with translations ([cf670af](https://github.com/AmruthPillai/Reactive-Resume/commit/cf670af4035dc9b462cf5b1aad06ca089cf1d40c))
* **client:** fix issues raised through lgtm alerts ([dfccb31](https://github.com/AmruthPillai/Reactive-Resume/commit/dfccb3130f889934d31196226be3d33e772f323b))
### [3.1.3](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.1.2...v3.1.3) (2022-03-12)
### Bug Fixes
* **server:** reform url for pdf generation and download ([6d55f91](https://github.com/AmruthPillai/Reactive-Resume/commit/6d55f917eab3cb2f5f3a90c5a18f03b625d60021)), closes [#661](https://github.com/AmruthPillai/Reactive-Resume/issues/661)
### [3.1.2](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.1.1...v3.1.2) (2022-03-12)
### CI
* **docker:**: include traefik routing and proxy to ensure server connections pass in local ([11cb066](https://github.com/AmruthPillai/Reactive-Resume/commit/11cb066573c6917857b79c028b97fcda1acaf90a))
### [3.1.1](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.1.0...v3.1.1) (2022-03-12)
### Features
* **client:** add product hunt announcement banner ([b515fc3](https://github.com/AmruthPillai/Reactive-Resume/commit/b515fc36e7f282db92e8eb509b6c5004a944fa95))
## [3.1.0](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.0.0...v3.1.0) (2022-03-12)
### Features
* **client:** add "spanish (es)" language to i18n locales ([bf167f8](https://github.com/AmruthPillai/Reactive-Resume/commit/bf167f81a3659677dada55856f5eaf0fc469e697))
* **client:** add mm/yyyy date option to date format options ([82bf44d](https://github.com/AmruthPillai/Reactive-Resume/commit/82bf44daa24422156779e9b38d3dc695176eaa09)), closes [#656](https://github.com/AmruthPillai/Reactive-Resume/issues/656)
* **client:** add sitemap generation to next app ([2cbc582](https://github.com/AmruthPillai/Reactive-Resume/commit/2cbc582a12b72b3012246022d4b518ed657d4c08))
* **client:** disable "Toggle Page Orientation" when there's only one page on the artboard ([01da1a0](https://github.com/AmruthPillai/Reactive-Resume/commit/01da1a06b802f1063a41d7a9a682e76b1daf9461)), closes [#655](https://github.com/AmruthPillai/Reactive-Resume/issues/655)
### Bug Fixes
* **client:** remove hard-coded "keywords:" in certain templates ([dda42b4](https://github.com/AmruthPillai/Reactive-Resume/commit/dda42b4c6b3bc359ac4f2bb91ca8118ddc84ec07)), closes [#650](https://github.com/AmruthPillai/Reactive-Resume/issues/650)
* **client:** show "present" string if end date is not entered, also add to i18n locales ([b5cd6c4](https://github.com/AmruthPillai/Reactive-Resume/commit/b5cd6c412b5b6b6ca7bb43c3801762de451f06b4)), closes [#653](https://github.com/AmruthPillai/Reactive-Resume/issues/653)
* **server:** photo uploads not working, fix save location and returned url ([799f208](https://github.com/AmruthPillai/Reactive-Resume/commit/799f20823e6d97a1ff0ba2c45c61d56304d0fa58)), closes [#658](https://github.com/AmruthPillai/Reactive-Resume/issues/658)
## [3.0.0](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.0.0-beta.6...v3.0.0) (2022-03-11)
### Features
* **lang**: add German, Kannada and Tamil languages to the app ([3a524f9](https://github.com/AmruthPillai/Reactive-Resume/commit/3a524f9c9c7a0e446491265b2242ad3dfeae188c))
* **docs:** add docusaurus workspace, initial setup of docs ([dc4aa0b](https://github.com/AmruthPillai/Reactive-Resume/commit/dc4aa0b496096bd59c45426bfcea6ba7db5f5c01))
## [3.0.0-beta.6](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.0.0-beta.5...v3.0.0-beta.6) (2022-03-11)
### Features
* **lang:** add language switcher on the landing page, in the footer ([8bc7d25](https://github.com/AmruthPillai/Reactive-Resume/commit/8bc7d2599ef6af7a07bfbe886c43844152b0d9f7))
### Bug Fixes
* **i18n:** add missing translation keys, update lang/locale logic ([7d8828a](https://github.com/AmruthPillai/Reactive-Resume/commit/7d8828a358d653bb162877a64c75028eb82678cd))
* **webkit:** fix issue with webkit not supporting .at() ([2654cba](https://github.com/AmruthPillai/Reactive-Resume/commit/2654cba039eb73d33257c36fa90a52cabc9fda96))
## [3.0.0-beta.5](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.0.0-beta.4...v3.0.0-beta.5) (2022-03-10)
### Bug Fixes
* **app:** fix issue with using swipelayout ([972e8b1](https://github.com/AmruthPillai/Reactive-Resume/commit/972e8b1bcf9ad44d8915bf23d189711672937bc0))

View File

@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities

View File

@ -56,19 +56,25 @@ You have complete control over what goes into your resume, how it looks, what co
- Arabic (اَلْعَرَبِيَّةُ)
- Bengali (বাংলা)
- Bulgarian (български)
- Chinese (中文)
- Czech (čeština)
- Danish (Dansk)
- Dutch (Nederlands)
- English
- Finnish (Suomi)
- French (Français)
- German (Deutsch)
- Greek (Ελληνικά)
- Hebrew (Ivrit)
- Hindi (हिन्दी)
- Hungarian (Magyar)
- Indonesian (Bahasa Indonesia)
- Italian (Italiano)
- Kannada (ಕನ್ನಡ)
- Malayalam (മലയാളം)
- Odia (ଓଡ଼ିଆ)
- Persian (Farsi)
- Polish (Polski)
- Portuguese (Português)
- Russian (русский)

View File

@ -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.6.21' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
}
task clean(type: Delete) {

View File

@ -1,9 +1,33 @@
{
"extends": ["../.eslintrc.json", "next/core-web-vitals"],
"extends": ["../.eslintrc.json", "next/core-web-vitals", "plugin:tailwindcss/recommended"],
"plugins": ["unused-imports"],
"ignorePatterns": [".next", "__ENV.js"],
"settings": {
"next": {
"rootDir": "client"
}
},
"rules": {
// Next.js
"@next/next/no-img-element": "off",
"@next/next/no-sync-scripts": "off",
"@next/next/no-html-link-for-pages": [2, "client/pages"]
// React Hooks
"react-hooks/exhaustive-deps": "off",
// Unused Imports
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
"vars": "all",
"args": "none",
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_"
}
],
// Tailwind CSS
"tailwindcss/no-custom-classname": ["warn", { "whitelist": ["preview-mode", "printer-mode", "markdown"] }]
}
}

3
client/.gitignore vendored
View File

@ -37,3 +37,6 @@ yarn-error.log*
# react-env
__ENV.js
# next-sitemap
sitemap*.xml

View File

@ -1,22 +1,19 @@
FROM node:lts-alpine as dependencies
RUN apk add --no-cache curl g++ make python3 \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
FROM node:lts-alpine AS base
WORKDIR /app
COPY package.json pnpm-*.yaml ./
RUN apk add --no-cache g++ git curl make python3 \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
FROM base as dependencies
COPY package.json pnpm-*.yaml turbo.json ./
COPY ./schema/package.json ./schema/package.json
COPY ./client/package.json ./client/package.json
RUN pnpm install --frozen-lockfile
FROM node:lts-alpine as builder
RUN apk add --no-cache curl g++ make python3 \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /app
FROM base as builder
COPY . .
@ -24,21 +21,20 @@ COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=dependencies /app/schema/node_modules ./schema/node_modules
COPY --from=dependencies /app/client/node_modules ./client/node_modules
RUN pnpm run build:schema
RUN pnpm run build:client
ARG TURBO_TEAM
ARG TURBO_TOKEN
FROM node:lts-alpine as production
ENV TURBO_TEAM $TURBO_TEAM
ENV TURBO_TOKEN $TURBO_TOKEN
WORKDIR /app
RUN pnpm run build --filter client
RUN apk add --no-cache curl \
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
FROM base as production
COPY --from=builder /app/pnpm-*.yaml ./
COPY --from=builder /app/package.json ./
COPY --from=builder /app/package.json /app/pnpm-*.yaml /app/turbo.json ./
COPY --from=builder /app/client/package.json ./client/package.json
RUN pnpm install -F client --frozen-lockfile --prod
RUN pnpm install --filter client --prod --frozen-lockfile --workspace-root
COPY --from=builder /app/client/.next ./client/.next
COPY --from=builder /app/client/public ./client/public
@ -52,4 +48,4 @@ ENV PORT 3000
HEALTHCHECK --interval=30s --timeout=20s --retries=3 --start-period=15s \
CMD curl -fSs 127.0.0.1:3000 || exit 1
CMD [ "pnpm", "run", "start:client" ]
CMD [ "pnpm", "run", "start", "--filter", "client" ]

View File

@ -5,6 +5,8 @@ import {
FilterCenterFocus,
InsertPageBreak,
Link,
RedoOutlined,
UndoOutlined,
ViewSidebar,
ZoomIn,
ZoomOut,
@ -16,6 +18,7 @@ import { useTranslation } from 'next-i18next';
import toast from 'react-hot-toast';
import { useMutation } from 'react-query';
import { ReactZoomPanPinchRef } from 'react-zoom-pan-pinch';
import { ActionCreators } from 'redux-undo';
import { ServerError } from '@/services/axios';
import { printResumeAsPdf, PrintResumeAsPdfParams } from '@/services/printer';
@ -31,14 +34,18 @@ const ArtboardController: React.FC<ReactZoomPanPinchRef> = ({ zoomIn, zoomOut, c
const theme = useTheme();
const dispatch = useAppDispatch();
const resume = useAppSelector((state) => state.resume);
const isDesktop = useMediaQuery(theme.breakpoints.up('sm'));
const pages = useAppSelector((state) => state.resume.metadata.layout);
const { past, present: resume, future } = useAppSelector((state) => state.resume);
const pages = get(resume, 'metadata.layout');
const { left, right } = useAppSelector((state) => state.build.sidebar);
const orientation = useAppSelector((state) => state.build.page.orientation);
const { mutateAsync, isLoading } = useMutation<string, ServerError, PrintResumeAsPdfParams>(printResumeAsPdf);
const handleUndo = () => dispatch(ActionCreators.undo());
const handleRedo = () => dispatch(ActionCreators.redo());
const handleTogglePageBreakLine = () => dispatch(togglePageBreakLine());
const handleTogglePageOrientation = () => dispatch(togglePageOrientation());
@ -75,6 +82,20 @@ const ArtboardController: React.FC<ReactZoomPanPinchRef> = ({ zoomIn, zoomOut, c
})}
>
<div className={styles.controller}>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.undo')}>
<ButtonBase onClick={handleUndo} className={clsx({ 'pointer-events-none opacity-50': past.length < 2 })}>
<UndoOutlined fontSize="medium" />
</ButtonBase>
</Tooltip>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.redo')}>
<ButtonBase onClick={handleRedo} className={clsx({ 'pointer-events-none opacity-50': future.length === 0 })}>
<RedoOutlined fontSize="medium" />
</ButtonBase>
</Tooltip>
<Divider />
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.zoom-in')}>
<ButtonBase onClick={() => zoomIn(0.25)}>
<ZoomIn fontSize="medium" />
@ -97,9 +118,11 @@ const ArtboardController: React.FC<ReactZoomPanPinchRef> = ({ zoomIn, zoomOut, c
{isDesktop && (
<>
{pages.length > 1 && (
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-orientation')}>
<ButtonBase onClick={handleTogglePageOrientation}>
<ButtonBase
onClick={handleTogglePageOrientation}
className={clsx({ 'pointer-events-none opacity-50': pages.length === 1 })}
>
{orientation === 'vertical' ? (
<AlignHorizontalCenter fontSize="medium" />
) : (
@ -107,7 +130,6 @@ const ArtboardController: React.FC<ReactZoomPanPinchRef> = ({ zoomIn, zoomOut, c
)}
</ButtonBase>
</Tooltip>
)}
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-page-break-line')}>
<ButtonBase onClick={handleTogglePageBreakLine}>

View File

@ -13,7 +13,7 @@ import Page from './Page';
const Center = () => {
const orientation = useAppSelector((state) => state.build.page.orientation);
const resume = useAppSelector((state) => state.resume);
const resume = useAppSelector((state) => state.resume.present);
const layout: string[][][] = get(resume, 'metadata.layout');
if (isEmpty(resume)) return null;

View File

@ -57,7 +57,7 @@ const Header = () => {
const { mutateAsync: deleteMutation } = useMutation<void, ServerError, DeleteResumeParams>(deleteResume);
const resume = useAppSelector((state) => state.resume);
const resume = useAppSelector((state) => state.resume.present);
const { left, right } = useAppSelector((state) => state.build.sidebar);
const name = useMemo(() => get(resume, 'name'), [resume]);

View File

@ -27,6 +27,13 @@
@apply hidden;
}
}
.markdown {
ul {
padding-left: 1.5em;
text-indent: -1.5em;
}
}
}
.pageNumber {

View File

@ -20,7 +20,7 @@ type Props = PageProps & {
const Page: React.FC<Props> = ({ page, showPageNumbers = false }) => {
const { t } = useTranslation();
const resume = useAppSelector((state) => state.resume);
const resume = useAppSelector((state) => state.resume.present);
const breakLine: boolean = useAppSelector((state) => state.build.page.breakLine);
const theme: Theme = get(resume, 'metadata.theme');

View File

@ -25,7 +25,7 @@ const LeftSidebar = () => {
const isDesktop = useMediaQuery(theme.breakpoints.up('lg'));
const sections = useAppSelector((state) => state.resume.sections);
const sections = useAppSelector((state) => state.resume.present.sections);
const { open } = useAppSelector((state) => state.build.sidebar.left);
const customSections = useMemo(() => getCustomSections(sections), [sections]);
@ -65,7 +65,7 @@ const LeftSidebar = () => {
variant={isDesktop ? 'persistent' : 'temporary'}
>
<div className={styles.container}>
<nav>
<nav className="overflow-y-scroll">
<div>
<Link href="/dashboard">
<a className="inline-flex">

View File

@ -32,7 +32,7 @@ const Basics = () => {
<PhotoUpload />
</div>
<div className="grid gap-2 w-full sm:col-span-2">
<div className="grid w-full gap-2 sm:col-span-2">
<ResumeInput label={t<string>('builder.leftSidebar.sections.basics.name.label')} path="basics.name" />
<Button variant="outlined" startIcon={<PhotoFilter />} onClick={handleClick}>

View File

@ -12,7 +12,7 @@ const PhotoFilters = () => {
const dispatch = useAppDispatch();
const photo: Photo = useAppSelector((state) => get(state.resume, 'basics.photo'));
const photo: Photo = useAppSelector((state) => get(state.resume.present, 'basics.photo'));
const size: number = get(photo, 'filters.size', 128);
const shape: PhotoShape = get(photo, 'filters.shape', 'square');
const grayscale: boolean = get(photo, 'filters.grayscale', false);

View File

@ -21,8 +21,8 @@ const PhotoUpload: React.FC = () => {
const fileInputRef = useRef<HTMLInputElement>(null);
const id: number = useAppSelector((state) => get(state.resume, 'id'));
const photo: Photo = useAppSelector((state) => get(state.resume, 'basics.photo'));
const id: number = useAppSelector((state) => get(state.resume.present, 'id'));
const photo: Photo = useAppSelector((state) => get(state.resume.present, 'basics.photo'));
const { mutateAsync: uploadMutation, isLoading } = useMutation<Resume, ServerError, UploadPhotoParams>(uploadPhoto);

View File

@ -37,8 +37,8 @@ const Section: React.FC<Props> = ({
const dispatch = useAppDispatch();
const heading = useAppSelector<string>((state) => get(state.resume, `${path}.name`, name));
const visibility = useAppSelector<boolean>((state) => get(state.resume, `${path}.visible`, true));
const heading = useAppSelector<string>((state) => get(state.resume.present, `${path}.name`, name));
const visibility = useAppSelector<boolean>((state) => get(state.resume.present, `${path}.visible`, true));
const handleAdd = () => {
const id = path.split('.')[1];

View File

@ -18,7 +18,7 @@ const SectionSettings: React.FC<Props> = ({ path }) => {
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const columns = useAppSelector<number>((state) => get(state.resume, `${path}.columns`, 2));
const columns = useAppSelector<number>((state) => get(state.resume.present, `${path}.columns`, 2));
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);

View File

@ -43,7 +43,7 @@ const RightSidebar = () => {
variant={isDesktop ? 'persistent' : 'temporary'}
>
<div className={styles.container}>
<nav>
<nav className="overflow-y-scroll">
<div>
<Avatar size={40} />
<Divider />

View File

@ -17,7 +17,7 @@ const CustomCSS = () => {
const dispatch = useAppDispatch();
const customCSS: CustomCSSType = useAppSelector((state) => get(state.resume, 'metadata.css', {}));
const customCSS: CustomCSSType = useAppSelector((state) => get(state.resume.present, 'metadata.css', {}));
const handleChange = (value: string | undefined) => {
dispatch(setResumeState({ path: 'metadata.css.value', value }));

View File

@ -13,7 +13,7 @@ import { useAppSelector } from '@/store/hooks';
const Export = () => {
const { t } = useTranslation();
const resume = useAppSelector((state) => state.resume);
const resume = useAppSelector((state) => state.resume.present);
const { mutateAsync, isLoading } = useMutation<string, ServerError, PrintResumeAsPdfParams>(printResumeAsPdf);

View File

@ -1,10 +1,10 @@
import { DragDropContext, Draggable, DraggableLocation, Droppable, DropResult } from '@hello-pangea/dnd';
import { Add, Close, Restore } from '@mui/icons-material';
import { Button, IconButton, Tooltip } from '@mui/material';
import clsx from 'clsx';
import cloneDeep from 'lodash/cloneDeep';
import get from 'lodash/get';
import { useTranslation } from 'next-i18next';
import { DragDropContext, Draggable, DraggableLocation, Droppable, DropResult } from 'react-beautiful-dnd';
import Heading from '@/components/shared/Heading';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
@ -23,8 +23,8 @@ const Layout = () => {
const dispatch = useAppDispatch();
const layout = useAppSelector((state) => state.resume.metadata.layout);
const resumeSections = useAppSelector((state) => state.resume.sections);
const layout = useAppSelector((state) => state.resume.present.metadata.layout);
const resumeSections = useAppSelector((state) => state.resume.present.sections);
const onDragEnd = (dropResult: DropResult) => {
const { source: srcLoc, destination: destLoc } = dropResult;

View File

@ -3,7 +3,7 @@ import { Button } from '@mui/material';
import { useTranslation } from 'next-i18next';
import Heading from '@/components/shared/Heading';
import { DONATION_URL, GITHUB_ISSUES_URL, GITHUB_URL } from '@/constants/index';
import { DOCS_URL, DONATION_URL, GITHUB_ISSUES_URL, GITHUB_URL } from '@/constants/index';
import styles from './Links.module.scss';
@ -49,6 +49,12 @@ const Links = () => {
{t<string>('builder.rightSidebar.sections.links.github')}
</Button>
</a>
<a href={DOCS_URL} target="_blank" rel="noreferrer">
<Button variant="text" startIcon={<Link />}>
{t<string>('builder.rightSidebar.sections.links.docs')}
</Button>
</a>
</div>
</div>
</>

View File

@ -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,9 +36,11 @@ const Settings = () => {
const { locale, ...router } = useRouter();
const resume = useAppSelector((state) => state.resume);
const [confirmReset, setConfirmReset] = useState(false);
const resume = useAppSelector((state) => state.resume.present);
const theme = useAppSelector((state) => state.build.theme);
const pages = useAppSelector((state) => state.resume.metadata.layout);
const pages = useAppSelector((state) => state.resume.present.metadata.layout);
const breakLine = useAppSelector((state) => state.build.page.breakLine);
const orientation = useAppSelector((state) => state.build.page.orientation);
@ -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 (
@ -90,7 +97,7 @@ const Settings = () => {
<List sx={{ padding: 0 }}>
{/* Global Settings */}
<>
<ListSubheader className="rounded">
<ListSubheader disableSticky className="rounded">
{t<string>('builder.rightSidebar.sections.settings.global.heading')}
</ListSubheader>
@ -148,7 +155,7 @@ const Settings = () => {
{/* Page Settings */}
<>
<ListSubheader className="rounded">
<ListSubheader disableSticky className="rounded">
{t<string>('builder.rightSidebar.sections.settings.page.heading')}
</ListSubheader>
@ -180,7 +187,7 @@ const Settings = () => {
{/* Resume Settings */}
<>
<ListSubheader className="rounded">
<ListSubheader disableSticky className="rounded">
{t<string>('builder.rightSidebar.sections.settings.resume.heading')}
</ListSubheader>
@ -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>

View File

@ -17,7 +17,7 @@ const Sharing = () => {
const [showShortUrl, setShowShortUrl] = useState(false);
const resume = useAppSelector((state) => state.resume);
const resume = useAppSelector((state) => state.resume.present);
const isPublic = useMemo(() => get(resume, 'public'), [resume]);
const url = useMemo(() => getResumeUrl(resume, { withHost: true }), [resume]);
const shortUrl = useMemo(() => getResumeUrl(resume, { withHost: true, shortUrl: true }), [resume]);

View File

@ -16,7 +16,7 @@ const Templates = () => {
const dispatch = useAppDispatch();
const currentTemplate: string = useAppSelector((state) => get(state.resume, 'metadata.template'));
const currentTemplate: string = useAppSelector((state) => get(state.resume.present, 'metadata.template'));
const handleChange = (template: TemplateMeta) => {
dispatch(setResumeState({ path: 'metadata.template', value: template.id }));
@ -31,7 +31,7 @@ const Templates = () => {
<div key={template.id} className={styles.template}>
<div className={clsx(styles.preview, { [styles.selected]: template.id === currentTemplate })}>
<ButtonBase onClick={() => handleChange(template)}>
<Image src={template.preview} alt={template.name} className="rounded-sm" layout="fill" />
<Image src={template.preview} alt={template.name} className="rounded-sm" layout="fill" priority />
</ButtonBase>
</div>

View File

@ -1,8 +1,8 @@
.container {
@apply grid sm:grid-cols-2 gap-4;
@apply grid gap-4 sm:grid-cols-2;
}
.colorOptions {
@apply col-span-2 mb-4;
@apply grid grid-cols-8 gap-y-2 justify-items-center;
@apply grid grid-cols-8 justify-items-center gap-y-2;
}

View File

@ -16,7 +16,9 @@ const Theme = () => {
const dispatch = useAppDispatch();
const { background, text, primary } = useAppSelector<ThemeType>((state) => get(state.resume, 'metadata.theme'));
const { background, text, primary } = useAppSelector<ThemeType>((state) =>
get(state.resume.present, 'metadata.theme')
);
const handleChange = (property: string, color: string) => {
dispatch(setResumeState({ path: `metadata.theme.${property}`, value: color[0] !== '#' ? `#${color}` : color }));

View File

@ -33,7 +33,7 @@ const Widgets: React.FC<WidgetProps> = ({ label, category }) => {
const dispatch = useAppDispatch();
const { family, size } = useAppSelector<TypographyType>((state) => get(state.resume, 'metadata.typography'));
const { family, size } = useAppSelector<TypographyType>((state) => get(state.resume.present, 'metadata.typography'));
const { data: fonts } = useQuery(FONTS_QUERY, fetchFonts, {
select: (fonts) => fonts.sort((a, b) => a.category.localeCompare(b.category)),

View File

@ -1,9 +1,9 @@
.testimony {
@apply grid gap-2;
@apply border-2 rounded p-4 dark:border-neutral-800;
@apply rounded border-2 p-4 dark:border-neutral-800;
blockquote {
@apply text-xs leading-normal text-justify opacity-90;
@apply text-justify text-xs leading-normal opacity-90;
}
figcaption {

View File

@ -10,7 +10,7 @@
}
.header {
@apply sticky top-0 left-0 right-0 z-50 pt-6 bg-neutral-50 dark:bg-neutral-900;
@apply sticky top-0 left-0 right-0 z-50 bg-neutral-50 pt-6 dark:bg-neutral-900;
@apply flex items-center justify-between;
@apply w-full border-b pb-5 dark:border-white/10;
@ -33,7 +33,7 @@
}
.footer {
@apply sticky bottom-0 left-0 right-0 z-50 pb-6 bg-neutral-50 dark:bg-neutral-900;
@apply sticky bottom-0 left-0 right-0 z-50 bg-neutral-50 pb-6 dark:bg-neutral-900;
@apply flex items-center justify-end gap-x-4;
@apply w-full border-t pt-5 dark:border-white/10;
}

View File

@ -32,8 +32,8 @@ const Heading: React.FC<Props> = ({
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`, name));
const visibility = useAppSelector((state) => get(state.resume, `${path}.visible`, true));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`, name));
const visibility = useAppSelector((state) => get(state.resume.present, `${path}.visible`, true));
const [editMode, setEditMode] = useState(false);

View File

@ -9,5 +9,5 @@
}
.language {
@apply py-2 px-4 cursor-pointer text-center hover:underline;
@apply cursor-pointer py-2 px-4 text-center hover:underline;
}

View File

@ -36,7 +36,7 @@ const List: React.FC<Props> = ({
const dispatch = useAppDispatch();
const list: Array<ListItemType> = useAppSelector((state) => get(state.resume, path, []));
const list: Array<ListItemType> = useAppSelector((state) => get(state.resume.present, path, []));
const handleEdit = (item: ListItemType) => {
isFunction(onEdit) && onEdit(item);

View File

@ -5,6 +5,7 @@ import styles from './Loading.module.scss';
const Loading: React.FC = () => {
const { isReady } = useRouter();
const isFetching = useIsFetching();
const isMutating = useIsMutating();

View File

@ -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';
@ -21,7 +21,7 @@ interface Props {
const ResumeInput: React.FC<Props> = ({ type = 'text', label, path, className, markdownSupported = false }) => {
const dispatch = useAppDispatch();
const stateValue = useAppSelector((state) => get(state.resume, path, ''));
const stateValue = useAppSelector((state) => get(state.resume.present, path, ''));
useEffect(() => {
setValue(stateValue);
@ -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());
}}
/>
);

View File

@ -6,26 +6,42 @@ export type Language = {
export const languages: Language[] = [
{ code: 'ar', name: 'Arabic', localName: 'اَلْعَرَبِيَّةُ' },
{ code: 'bg', name: 'Bulgarian', localName: 'български' },
{ code: 'bn', name: 'Bengali', localName: 'বাংলা' },
{ code: 'ca', name: 'Catalan', localName: 'Valencian' },
{ code: 'cs', name: 'Czech', localName: 'čeština' },
{ code: 'da', name: 'Danish', localName: 'Dansk' },
{ code: 'de', name: 'German', localName: 'Deutsch' },
{ code: 'el', name: 'Greek', localName: 'Ελληνικά' },
{ code: 'en', name: 'English' },
{ code: 'es', name: 'Spanish', localName: 'Español' },
{ code: 'fa', name: 'Persian', localName: 'فارسی' },
{ code: 'fi', name: 'Finnish', localName: 'Suomi' },
{ code: 'fr', name: 'French', localName: 'Français' },
{ code: 'he', name: 'Hebrew', localName: 'Ivrit' },
{ code: 'hi', name: 'Hindi', localName: 'हिन्दी' },
{ code: 'hu', name: 'Hungarian', localName: 'Magyar' },
{ code: 'id', name: 'Indonesian', localName: 'Bahasa Indonesia' },
{ code: 'it', name: 'Italian', localName: 'Italiano' },
{ code: 'ja', name: 'Japanese', localName: '日本語' },
{ code: 'km', name: 'Khmer', localName: 'ភាសាខ្មែរ' },
{ code: 'kn', name: 'Kannada', localName: 'ಕನ್ನಡ' },
{ code: 'ko', name: 'Korean', localName: '한국어' },
{ code: 'ml', name: 'Malayalam', localName: 'മലയാളം' },
{ code: 'mr', name: 'Marathi', localName: 'मराठी' },
{ code: 'ne', name: 'Nepali', localName: 'नेपाली' },
{ code: 'nl', name: 'Dutch', localName: 'Nederlands' },
{ code: 'no', name: 'Norwegian', localName: 'Norsk' },
{ code: 'or', name: 'Odia', localName: 'ଓଡ଼ିଆ' },
{ code: 'pl', name: 'Polish', localName: 'Polski' },
{ code: 'pt', name: 'Portuguese', localName: 'Português' },
{ code: 'ro', name: 'Romanian', localName: 'limba română' },
{ code: 'ru', name: 'Russian', localName: 'русский' },
{ code: 'sr', name: 'Serbian', localName: 'српски језик' },
{ code: 'sv', name: 'Swedish', localName: 'Svenska' },
{ code: 'ta', name: 'Tamil', localName: 'தமிழ்' },
{ code: 'tr', name: 'Turkish', localName: 'Türkçe' },
{ code: 'uk', name: 'Ukranian', localName: 'Українська мова' },
{ code: 'vi', name: 'Vietnamese', localName: 'Tiếng Việt' },
{ code: 'zh', name: 'Chinese', localName: '中文' },
].sort((a, b) => a.name.localeCompare(b.name));

View File

@ -1,6 +1,6 @@
import { createTheme } from '@mui/material';
import { createTheme, ThemeOptions } from '@mui/material/styles';
const theme = createTheme({
const theme: ThemeOptions = {
typography: {
fontSize: 12,
fontFamily: 'Inter, sans-serif',
@ -49,7 +49,7 @@ const theme = createTheme({
},
},
},
});
};
export const lightTheme = createTheme({
...theme,

View File

@ -9,6 +9,7 @@ export const VALID_URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}
export const FILENAME_TIMESTAMP = 'DDMMYYYYHHmmss';
// Links
export const DOCS_URL = 'https://docs.rxresu.me';
export const DONATION_URL = 'https://paypal.me/RajaRajanA';
export const TRANSLATE_URL = 'https://translate.rxresu.me/';
export const DIGITALOCEAN_URL = 'https://pillai.xyz/digitalocean';

View File

@ -1,7 +1,8 @@
import env from '@beam-australia/react-env';
import { joiResolver } from '@hookform/resolvers/joi';
import { Google, Login, Visibility, VisibilityOff } from '@mui/icons-material';
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 { Trans, useTranslation } from 'next-i18next';
@ -17,8 +18,6 @@ import { ServerError } from '@/services/axios';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setModalState } from '@/store/modal/modalSlice';
declare const google: any;
type FormData = {
identifier: string;
password: string;
@ -85,18 +84,16 @@ const LoginModal: React.FC = () => {
dispatch(setModalState({ modal: 'auth.forgot', state: { open: true } }));
};
const handleLoginWithGoogle = async () => {
google.accounts.id.initialize({
client_id: env('GOOGLE_CLIENT_ID'),
callback: async (response: any) => {
await loginWithGoogleMutation({ credential: response.credential });
const handleLoginWithGoogle = async (response: CredentialResponse) => {
if (response.credential) {
await loginWithGoogleMutation({ credential: response.credential }, { onError: handleLoginWithGoogleError });
handleClose();
},
auto_select: false,
});
}
};
google.accounts.id.prompt();
const handleLoginWithGoogleError = () => {
toast("Please try logging in using email/password, or use another browser that supports Google's One Tap API.");
};
const PasswordVisibility = (): React.ReactElement => {
@ -120,15 +117,7 @@ const LoginModal: React.FC = () => {
footerChildren={
<div className="flex gap-4">
{!isEmpty(env('GOOGLE_CLIENT_ID')) && (
<Button
type="submit"
variant="outlined"
disabled={isLoading}
startIcon={<Google />}
onClick={handleLoginWithGoogle}
>
{t<string>('modals.auth.login.actions.google')}
</Button>
<GoogleLogin onSuccess={handleLoginWithGoogle} onError={handleLoginWithGoogleError} />
)}
<Button type="submit" onClick={handleSubmit(onSubmit)} disabled={isLoading}>

View File

@ -1,11 +1,13 @@
import env from '@beam-australia/react-env';
import { joiResolver } from '@hookform/resolvers/joi';
import { Google, HowToReg } from '@mui/icons-material';
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 { Trans, useTranslation } from 'next-i18next';
import { Controller, useForm } from 'react-hook-form';
import toast from 'react-hot-toast';
import { useMutation } from 'react-query';
import BaseModal from '@/components/shared/BaseModal';
@ -14,8 +16,6 @@ import { ServerError } from '@/services/axios';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setModalState } from '@/store/modal/modalSlice';
declare const google: any;
type FormData = {
name: string;
username: string;
@ -79,18 +79,16 @@ const RegisterModal: React.FC = () => {
dispatch(setModalState({ modal: 'auth.login', state: { open: true } }));
};
const handleLoginWithGoogle = async () => {
google.accounts.id.initialize({
client_id: env('GOOGLE_CLIENT_ID'),
callback: async (response: any) => {
await loginWithGoogleMutation({ credential: response.credential });
const handleLoginWithGoogle = async (response: CredentialResponse) => {
if (response.credential) {
await loginWithGoogleMutation({ credential: response.credential }, { onError: handleLoginWithGoogleError });
handleClose();
},
auto_select: false,
});
}
};
google.accounts.id.prompt();
const handleLoginWithGoogleError = () => {
toast("Please try logging in using email/password, or use another browser that supports Google's One Tap API.");
};
return (
@ -102,15 +100,7 @@ const RegisterModal: React.FC = () => {
footerChildren={
<div className="flex gap-4">
{!isEmpty(env('GOOGLE_CLIENT_ID')) && (
<Button
type="submit"
variant="outlined"
disabled={isLoading}
startIcon={<Google />}
onClick={handleLoginWithGoogle}
>
{t<string>('modals.auth.register.actions.google')}
</Button>
<GoogleLogin onSuccess={handleLoginWithGoogle} onError={handleLoginWithGoogleError} />
)}
<Button type="submit" onClick={handleSubmit(onSubmit)} disabled={isLoading}>

View File

@ -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';
@ -44,7 +44,7 @@ const AwardModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);
@ -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

View File

@ -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';
@ -44,7 +44,7 @@ const CertificateModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);
@ -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

View File

@ -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';
@ -60,7 +60,7 @@ const CustomModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal['builder.sections.custom']);
const path: string = get(payload, 'path', '');
@ -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

View File

@ -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';
@ -57,7 +57,7 @@ const EducationModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);
@ -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

View File

@ -35,7 +35,7 @@ const InterestModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);

View File

@ -36,7 +36,7 @@ const LanguageModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);

View File

@ -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';
@ -53,7 +53,7 @@ const ProjectModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);
@ -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

View File

@ -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';
@ -44,7 +44,7 @@ const PublicationModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);
@ -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

View File

@ -41,7 +41,7 @@ const ReferenceModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);

View File

@ -39,7 +39,7 @@ const SkillModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);

View File

@ -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';
@ -50,7 +50,7 @@ const VolunteerModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);
@ -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

View File

@ -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';
@ -50,7 +50,7 @@ const WorkModal: React.FC = () => {
const dispatch = useAppDispatch();
const heading = useAppSelector((state) => get(state.resume, `${path}.name`));
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
const item: FormData = get(payload, 'item', null);
@ -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

View File

@ -69,7 +69,8 @@ const CreateResumeModal: React.FC = () => {
try {
await mutateAsync({ name, slug, public: isPublic });
queryClient.invalidateQueries(RESUMES_QUERY);
await queryClient.invalidateQueries(RESUMES_QUERY);
handleClose();
} catch (error: any) {
toast.error(error.message);

View File

@ -5,22 +5,42 @@ const i18nConfig = {
defaultLocale: 'en',
locales: [
'ar',
'bg',
'bn',
'ca',
'cs',
'da',
'de',
'el',
'en',
'es',
'fa',
'fi',
'fr',
'he',
'hi',
'hu',
'id',
'it',
'ja',
'km',
'kn',
'ko',
'ml',
'mr',
'ne',
'nl',
'no',
'or',
'pl',
'pt',
'ro',
'ru',
'sr',
'sv',
'ta',
'tr',
'uk',
'vi',
'zh',
],

View File

@ -15,19 +15,6 @@ const nextConfig = {
domains: ['cdn.rxresu.me', 'www.gravatar.com'],
},
async rewrites() {
if (process.env.NODE_ENV === 'development') {
return [
{
source: '/api/:path*',
destination: 'http://localhost:3100/:path*',
},
];
}
return [];
},
// Hack to make Tailwind darkMode 'class' strategy with CSS Modules
// Ref: https://github.com/tailwindlabs/tailwindcss/issues/3258#issuecomment-968368156
webpack: (config) => {

View File

@ -2,77 +2,83 @@
"name": "@reactive-resume/client",
"scripts": {
"dev": "react-env --prefix PUBLIC -- next dev",
"lint": "next lint --fix",
"build": "next build && npm run sitemap",
"start": "react-env --prefix PUBLIC -- next start",
"lint": "next lint --fix",
"sitemap": "next-sitemap --config next-sitemap.config.js"
},
"dependencies": {
"@beam-australia/react-env": "^3.1.1",
"@emotion/css": "^11.9.0",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@hookform/resolvers": "2.8.8",
"@monaco-editor/react": "^4.4.4",
"@mui/icons-material": "^5.6.2",
"@mui/lab": "^5.0.0-alpha.79",
"@mui/material": "^5.6.3",
"@reduxjs/toolkit": "^1.8.1",
"@date-io/dayjs": "^2.15.0",
"@emotion/css": "^11.10.0",
"@emotion/react": "^11.10.0",
"@emotion/styled": "^11.10.0",
"@hello-pangea/dnd": "^16.0.0",
"@hookform/resolvers": "2.9.7",
"@monaco-editor/react": "^4.4.5",
"@mui/icons-material": "^5.10.3",
"@mui/lab": "^5.0.0-alpha.97",
"@mui/material": "^5.10.3",
"@mui/system": "^5.10.3",
"@mui/x-date-pickers": "5.0.0-beta.7",
"@next/env": "^12.2.5",
"@react-oauth/google": "^0.2.6",
"@reduxjs/toolkit": "^1.8.5",
"axios": "^0.27.2",
"clsx": "^1.1.1",
"dayjs": "^1.11.1",
"clsx": "^1.2.1",
"dayjs": "^1.11.5",
"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.3",
"next": "12.1.5",
"next-i18next": "^11.0.0",
"react": "^18",
"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",
"react-hook-form": "^7.30.0",
"react-hot-toast": "2.2.0",
"react-hotkeys-hook": "^3.4.4",
"react-icons": "^4.3.1",
"monaco-editor": "^0.34.0",
"nanoid": "^3.3.4",
"next": "12.2.5",
"next-i18next": "^12.0.0",
"react": "^18.2.0",
"react-colorful": "^5.6.1",
"react-dnd": "16.0.1",
"react-dnd-html5-backend": "16.0.1",
"react-dom": "^18.2.0",
"react-hook-form": "^7.34.2",
"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.38.0",
"react-redux": "^8.0.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",
"redux-saga": "^1.2.1",
"redux-undo": "^1.0.1",
"remark-gfm": "^3.0.1",
"sharp": "^0.30.4",
"sharp": "^0.30.7",
"uuid": "^8.3.2",
"webfontloader": "^1.6.28"
},
"devDependencies": {
"@babel/core": "^7.17.10",
"@babel/core": "^7.18.13",
"@reactive-resume/schema": "workspace:*",
"@tailwindcss/typography": "^0.5.2",
"eslint-plugin-unused-imports": "^2.0.0",
"@tailwindcss/typography": "^0.5.4",
"@types/downloadjs": "^1.4.3",
"@types/lodash": "^4.14.182",
"@types/node": "17.0.30",
"@types/react": "^18",
"@types/react-beautiful-dnd": "^13.1.2",
"@types/lodash": "^4.14.184",
"@types/node": "^18.7.13",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@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.5",
"csstype": "^3.0.11",
"eslint": "^8.14.0",
"eslint-config-next": "12.1.5",
"next-sitemap": "^2.5.20",
"postcss": "^8.4.13",
"prettier": "^2.6.2",
"sass": "^1.51.0",
"tailwindcss": "^3.0.24",
"typescript": "^4.6.4"
"autoprefixer": "^10.4.8",
"csstype": "^3.1.0",
"eslint-config-next": "^12.2.5",
"eslint-plugin-tailwindcss": "^3.6.0",
"next-sitemap": "^3.1.21",
"postcss": "^8.4.16",
"sass": "^1.54.5",
"tailwindcss": "^3.1.8",
"typescript": "^4.8.2"
}
}

View File

@ -51,7 +51,7 @@ const Preview: NextPage<Props> = ({ username, slug, resume: initialData }) => {
const dispatch = useAppDispatch();
const resume = useAppSelector((state) => state.resume);
const resume = useAppSelector((state) => state.resume.present);
useEffect(() => {
if (initialData && !isEmpty(initialData)) {
@ -59,6 +59,14 @@ const Preview: NextPage<Props> = ({ username, slug, resume: initialData }) => {
}
}, [dispatch, initialData]);
useEffect(() => {
if (!isEmpty(resume) && router.locale !== resume.metadata.locale) {
const { pathname, asPath, query } = router;
router.push({ pathname, query }, asPath, { locale: resume.metadata.locale });
}
}, [resume, router]);
useQuery<Resume>(`resume/${username}/${slug}`, () => fetchResumeByIdentifier({ username, slug }), {
initialData,
retry: false,

View File

@ -3,7 +3,6 @@ import clsx from 'clsx';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import { GetServerSideProps, NextPage } from 'next';
import { useRouter } from 'next/router';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useEffect } from 'react';
@ -55,22 +54,14 @@ export const getServerSideProps: GetServerSideProps<Props | Promise<Props>, Quer
};
const Printer: NextPage<Props> = ({ resume: initialData, locale }) => {
const router = useRouter();
const dispatch = useAppDispatch();
const resume = useAppSelector((state) => state.resume);
const resume = useAppSelector((state) => state.resume.present);
useEffect(() => {
if (initialData) dispatch(setResume(initialData));
}, [dispatch, initialData]);
useEffect(() => {
const { pathname, asPath, query } = router;
router.push({ pathname, query }, asPath, { locale });
}, [router, locale]);
if (!resume || isEmpty(resume)) return null;
const layout: string[][][] = get(resume, 'metadata.layout', []);

View File

@ -1,10 +1,11 @@
import '@/styles/globals.scss';
import DateAdapter from '@mui/lab/AdapterDayjs';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import env from '@beam-australia/react-env';
import DayjsAdapter from '@date-io/dayjs';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { GoogleOAuthProvider } from '@react-oauth/google';
import type { AppProps } from 'next/app';
import Head from 'next/head';
import Script from 'next/script';
import { appWithTranslation } from 'next-i18next';
import { Toaster } from 'react-hot-toast';
import { QueryClientProvider } from 'react-query';
@ -17,8 +18,7 @@ import queryClient from '@/services/react-query';
import store, { persistor } from '@/store/index';
import WrapperRegistry from '@/wrappers/index';
const App: React.FC<AppProps> = ({ Component, pageProps }) => {
return (
const App: React.FC<AppProps> = ({ Component, pageProps }) => (
<>
<Head>
<title>Reactive Resume</title>
@ -32,8 +32,9 @@ const App: React.FC<AppProps> = ({ Component, pageProps }) => {
</Head>
<ReduxProvider store={store}>
<LocalizationProvider dateAdapter={DateAdapter}>
<LocalizationProvider dateAdapter={DayjsAdapter}>
<PersistGate loading={null} persistor={persistor}>
<GoogleOAuthProvider clientId={env('GOOGLE_CLIENT_ID')}>
<QueryClientProvider client={queryClient}>
<WrapperRegistry>
<Loading />
@ -50,13 +51,11 @@ const App: React.FC<AppProps> = ({ Component, pageProps }) => {
/>
</WrapperRegistry>
</QueryClientProvider>
</GoogleOAuthProvider>
</PersistGate>
</LocalizationProvider>
</ReduxProvider>
<Script src="https://accounts.google.com/gsi/client" />
</>
);
};
export default appWithTranslation(App);

View File

@ -4,7 +4,9 @@ import Head from 'next/head';
import Link from 'next/link';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useEffect } from 'react';
import { useQuery } from 'react-query';
import { ActionCreators } from 'redux-undo';
import ResumeCard from '@/components/dashboard/ResumeCard';
import ResumePreview from '@/components/dashboard/ResumePreview';
@ -12,6 +14,7 @@ import Avatar from '@/components/shared/Avatar';
import Logo from '@/components/shared/Logo';
import { RESUMES_QUERY } from '@/constants/index';
import { fetchResumes } from '@/services/resume';
import { useAppDispatch } from '@/store/hooks';
import styles from '@/styles/pages/Dashboard.module.scss';
export const getStaticProps: GetStaticProps = async ({ locale = 'en' }) => {
@ -25,8 +28,14 @@ export const getStaticProps: GetStaticProps = async ({ locale = 'en' }) => {
const Dashboard: NextPage = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const { data } = useQuery(RESUMES_QUERY, fetchResumes);
useEffect(() => {
dispatch(ActionCreators.clearHistory());
}, []);
if (!data) return null;
return (

View File

@ -20,7 +20,7 @@ import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setModalState } from '@/store/modal/modalSlice';
import styles from '@/styles/pages/Home.module.scss';
import { DIGITALOCEAN_URL, DONATION_URL, GITHUB_URL } from '../constants';
import { DIGITALOCEAN_URL, DOCS_URL, DONATION_URL, GITHUB_URL } from '../constants';
export const getStaticProps: GetStaticProps = async ({ locale = 'en' }) => {
return {
@ -170,6 +170,12 @@ const Home: NextPage = () => {
</Button>
</a>
<a href={DOCS_URL} target="_blank" rel="noreferrer">
<Button variant="text" startIcon={<LinkIcon />}>
{t<string>('landing.links.links.docs')}
</Button>
</a>
<a href={DONATION_URL} target="_blank" rel="noreferrer">
<Button variant="text" startIcon={<LinkIcon />}>
{t<string>('landing.links.links.donate')}

View File

@ -1,7 +1,7 @@
import { NextPage } from 'next';
const PrivacyPolicy: NextPage = () => (
<div className="mx-auto my-12 prose dark:prose-invert">
<div className="prose mx-auto my-12 dark:prose-invert">
<h1>Privacy Policy</h1>
<p>

View File

@ -1,7 +1,7 @@
import { NextPage } from 'next';
const TermsOfService: NextPage = () => (
<div className="mx-auto my-12 prose dark:prose-invert">
<div className="prose mx-auto my-12 dark:prose-invert">
<h1>Terms of Service</h1>
<p>

View File

@ -7,6 +7,7 @@ import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import { GetServerSideProps, NextPage } from 'next';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useEffect } from 'react';
import toast from 'react-hot-toast';
@ -35,6 +36,8 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ query, loc
};
const Preview: NextPage<Props> = ({ shortId }) => {
const router = useRouter();
const dispatch = useAppDispatch();
const { data: resume } = useQuery<Resume>(`resume/${shortId}`, () => fetchResumeByShortId({ shortId }), {
@ -52,6 +55,14 @@ const Preview: NextPage<Props> = ({ shortId }) => {
if (resume) dispatch(setResume(resume));
}, [resume, dispatch]);
useEffect(() => {
if (resume && !isEmpty(resume) && router.locale !== resume.metadata.locale) {
const { pathname, asPath, query } = router;
router.push({ pathname, query }, asPath, { locale: resume.metadata.locale });
}
}, [resume, router]);
if (!resume || isEmpty(resume)) return null;
const layout: string[][][] = get(resume, 'metadata.layout', []);

View File

@ -1,9 +1,9 @@
{
"common": {
"actions": {
"add": "إضافة {{فقرة}} جديدة",
"delete": "حذة {{الفقرة}}",
"edit": "تحرير {{الفقرة}}"
"add": "إضافة {{token}} جديدة",
"delete": "حذف {{token}}",
"edit": "تحرير {{token}}"
},
"columns": {
"heading": "الأعمدة",
@ -24,13 +24,13 @@
"label": "تاريخ الانتهاء"
},
"keywords": {
"label": "الكلمات الرئيسية"
"label": "الكلمات الدالة"
},
"level": {
"label": "مستوى"
},
"levelNum": {
"label": "المستوى (Number)"
"label": "المستوى (العدد)"
},
"name": {
"label": "الاسم"
@ -42,7 +42,7 @@
"label": "المنصب"
},
"start-date": {
"label": "تاريخ البداية"
"label": "تاريخ البدء"
},
"subtitle": {
"label": "العنوان الفرعي"
@ -84,7 +84,9 @@
"toggle-page-break-line": "تبديل سطر الصفحة",
"toggle-sidebars": "تبديل الشريط الجانبي",
"zoom-in": "تكبير",
"zoom-out": "تصغير"
"zoom-out": "تصغير",
"undo": "الغاء التحميل",
"redo": "إعادة"
}
},
"header": {
@ -119,6 +121,9 @@
"name": {
"label": "الاسم الكامل"
},
"birthdate": {
"label": "تاريخ الميلاد"
},
"photo-filters": {
"effects": {
"border": {
@ -265,6 +270,7 @@
"heading": "تبرع الى Reactive Resume"
},
"github": "الشفرة المصدرية",
"docs": "توثيق",
"heading": "الروابط"
},
"settings": {

View File

@ -22,6 +22,7 @@
"links": {
"donate": "تبرّع",
"github": "الشفرة المصدرية",
"docs": "توثيق",
"privacy": "سياسة الخصوصية",
"service": "شروط الإستخدام"
}

View File

@ -15,8 +15,7 @@
},
"login": {
"actions": {
"login": "تسجيل الدخول",
"google": "تسجيل الدخول باستخدام حساب جوجل"
"login": "تسجيل الدخول"
},
"body": "يرجى إدخال اسم المستخدم وكلمة المرور المرتبطين بحسابك لتسجيل الدخول والوصول إلى السير الذاتية وإدارتها ومشاركتها.",
"form": {

View File

@ -0,0 +1,364 @@
{
"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": "Намали",
"undo": "Отмяна на",
"redo": "Redo"
}
},
"header": {
"menu": {
"delete": "Изтрии",
"duplicate": "Дубликирай",
"rename": "Преименувай",
"share-link": "Споделяне на връзка",
"tooltips": {
"delete": "Наистина ли искате да изтриете това CV? Това действие не може да бъде отменено.",
"share-link": "Трябва да промените видимостта на CV-то си на публична, за да я направите видима за другите."
}
}
},
"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": "Размер (в px)"
}
},
"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 версия на вашата автобиография, която може да бъде импортирана обратно в Reactive Resume."
},
"pdf": {
"loading": {
"primary": "Генериране на PDF",
"secondary": "Моля, изчакайте, докато вашият PDF се генерира, това може да отнеме до 15 секунди."
},
"normal": {
"primary": "РDF",
"secondary": "Изтеглете PDF файл на вашата автобиография, който можете да отпечатате и изпратите до мечтаната работа. Този файл не може да бъде импортиран обратно за по-нататъшно редактиране."
}
}
},
"layout": {
"heading": "Оформление",
"tooltip": {
"reset-layout": "Рестартирай оформлението"
}
},
"links": {
"bugs-features": {
"body": "Нещо ви пречи да си направите автобиография? Или имате невероятна идея, която да добавите? Повдигнете въпрос в GitHub, за да започнете.",
"button": "GitHub общност",
"heading": "Бъгове? Искания за функции?"
},
"donate": {
"body": "Ако ви е харесало да използвате Reactive Resume, моля, помислете дали да не дарите колкото можете повече за поддръжка на приложението, без реклами и безплатно завинаги.",
"button": "Почерпете ме с кафе",
"heading": "Направи дарение и подкрепи Reactive Resume"
},
"github": "Програмен код",
"docs": "Документация",
"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": "Позволете на всеки с връзка да види това CV",
"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": "Заглавия"
}
}
}
}
}
}

View File

@ -0,0 +1,29 @@
{
"avatar": {
"menu": {
"greeting": "Здравейте",
"logout": "Изход"
}
},
"footer": {
"credit": "Проект от <1>Амрут Пилай</1>",
"license": "От общността, за общността."
},
"markdown": {
"help-text": "Този раздел поддържа <1>markdown</1> форматиране."
},
"date": {
"present": "Настояще"
},
"subtitle": "Безплатен инструмент за създаване на автобиография с отворен код.",
"title": "Reactive Resume",
"toast": {
"error": {
"upload-file-size": "Моля, качвайте само файлове с размер под 2 мегабайта.",
"upload-photo-size": "Моля, качвайте само снимки под 2 мегабайта, за предпочитане квадратни."
},
"success": {
"resume-link-copied": "Връзката към автобиографията ви е копирана в клипборда."
}
}
}

View File

@ -0,0 +1,25 @@
{
"create-resume": {
"subtitle": "Започване отначало",
"title": "Създаване на ново CV"
},
"import-external": {
"subtitle": "LinkedIn, JSON резюме, Reactive Resume",
"title": "Импортиране от външни източници"
},
"resume": {
"menu": {
"delete": "Изтрии",
"duplicate": "Дубликирай",
"open": "Отвори",
"rename": "Преименувай",
"share-link": "Споделяне на връзка",
"tooltips": {
"delete": "Наистина ли искате да изтриете това CV? Това действие не може да бъде отменено.",
"share-link": "Трябва да промените видимостта на CV-то си на публична, за да я направите видима за другите."
}
},
"timestamp": "Последната промяна е преди {{timestamp}}"
},
"title": "Контролен панел"
}

View File

@ -0,0 +1,42 @@
{
"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": "Програмен код",
"docs": "Документация",
"privacy": "Политика за поверителност",
"service": "Условия на ползване"
}
},
"screenshots": {
"heading": "Екранни снимки"
},
"testimonials": {
"heading": "Препоръки",
"body": "Позитивно или негативно, ще се радвам да чуя мнението ви за Reactive Resume и какъв е вашия опитът.<br/>Ето някои от съобщенията, изпратени от потребители по целия свят.",
"contact": "Можете да се свържете с мен чрез <1>моя имейл</1> или чрез формата за контакт на <3>моя уебсайт</3> ."
},
"summary": {
"body": "Reactive Resume е безплатен инструмент за създаване на автобиография/CV с отворен код, който е създаден, за да улесни обикновените задачи за създаване, актуализиране и споделяне на вашата автобиография като 1, 2, 3. С това приложение можете да създавате множество автобиографии, да ги споделяте директно със специалистите по подбор на персонал или приятели чрез уникална връзка, както и ги отпечатате като PDF. Всичко е безплатно, без реклами, без проследяване, без да губите целостта и поверителността на вашите данни.",
"heading": "Обобщение"
}
}

View File

@ -0,0 +1,135 @@
{
"auth": {
"forgot-password": {
"actions": {
"send-email": "Възстановяване на парола"
},
"body": "Просто въведете имейл адреса, свързан с акаунта, който искате да възстановите.",
"form": {
"email": {
"label": "Имейл адрес"
}
},
"heading": "Забравена парола?",
"help-text": "Ако профилът ви съществува, ще получите линк за възстановяване на паролата."
},
"login": {
"actions": {
"login": "Вход"
},
"body": "Моля, въведете вашето потребителско име и парола, свързани с вашия акаунт, за да влезете и получите достъп, управлявате и споделяте вашите автобиографии.",
"form": {
"password": {
"label": "Парола"
},
"username": {
"help-text": "Можете също да въведете своя имейл адрес",
"label": "Потребителско име"
}
},
"heading": "Влезте във Вашият профил",
"recover-text": "В случай, че сте забравили паролата си, можете <1>да възстановите акаунта си</1> тук.",
"register-text": "Ако нямате такъв, можете <1>да си създадете акаунт</1> тук."
},
"register": {
"actions": {
"register": "Регистрация",
"google": "Регистрация с 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": "Създай CV/Резюме"
},
"body": "Започнете да създавате автобиографията си, като й дадете име. Може да е във връзка с позицията, за която кандидатствате, или просто любимата ви закуска.",
"form": {
"name": {
"label": "Име"
},
"public": {
"label": "Публично достъпна ли е?"
},
"slug": {
"label": "Слъг"
}
},
"heading": "Създаване на ново CV"
},
"import-external": {
"heading": "Импортиране от външни източници",
"json-resume": {
"actions": {
"upload-json": "Качване на JSON"
},
"body": "Ако имате готова <1>валидирана JSON автобиография</1>, можете да я използвате, за да стартирате бързо в Reactive Resume. Щракнете върху бутона по-долу и качете валиден JSON файл, за да започнете.",
"heading": "Качване на JSON Resume"
},
"linkedin": {
"actions": {
"upload-archive": "Качете ZIP архив"
},
"body": "Можете да спестите време, като експортирате данните си от LinkedIn и ги използвате за автоматично попълване на полета в Reactive Resume. Отидете в раздел <1>Поверителност на данните</1> в LinkedIn и поискайте архив на вашите данни. След като е наличен, качете ZIP файла по-долу.",
"heading": "Импортиране от LinkedIn"
},
"reactive-resume": {
"actions": {
"upload-json": "Качване на JSON",
"upload-json-v2": "Качете JSON от v2"
},
"body": "Ако имате JSON, който е бил експортиран с текущата версия на Reactive Resume, можете да го импортирате обратно тук, за да получите отново редактируема версия.",
"heading": "Импортиране от Reactive Resume"
}
},
"rename-resume": {
"actions": {
"rename-resume": "Преименуване на резюмето"
},
"form": {
"name": {
"label": "Име"
},
"slug": {
"label": "Слъг"
}
},
"heading": "Преименувайте автобиографията си"
}
}
}

View File

@ -84,7 +84,9 @@
"toggle-page-break-line": "পৃষ্ঠা বিরতি লাইন টগল করুন",
"toggle-sidebars": "সাইডবার টগল করুন",
"zoom-in": "বড় কর",
"zoom-out": "ছোট করা"
"zoom-out": "ছোট করা",
"undo": "পূর্বাবস্থায় ফেরান",
"redo": "আবার করুন"
}
},
"header": {
@ -119,6 +121,9 @@
"name": {
"label": "পূর্ণ নাম"
},
"birthdate": {
"label": "জন্ম তারিখ"
},
"photo-filters": {
"effects": {
"border": {
@ -265,6 +270,7 @@
"heading": "Reactive Resume -তে দান করুন"
},
"github": "সোর্স কোড",
"docs": "ডকুমেন্টেশন",
"heading": "লিঙ্ক"
},
"settings": {

View File

@ -22,6 +22,7 @@
"links": {
"donate": "দান করুন",
"github": "সোর্স কোড",
"docs": "ডকুমেন্টেশন",
"privacy": "গোপনীয়তা নীতি",
"service": "সেবা পাবার শর্ত"
}

View File

@ -15,8 +15,7 @@
},
"login": {
"actions": {
"login": "লগইন",
"google": "গুগল দিয়ে লগইন করুন"
"login": "লগইন"
},
"body": "লগইন এবং অ্যাক্সেস, পরিচালনা এবং আপনার জীবনবৃত্তান্ত শেয়ার করতে আপনার অ্যাকাউন্টের সাথে যুক্ত আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড লিখুন।",
"form": {

View File

@ -0,0 +1,364 @@
{
"common": {
"actions": {
"add": "Afegeix nou {{token}}",
"delete": "Suprimeix {{token}}",
"edit": "Edita {{token}}"
},
"columns": {
"heading": "Columnes",
"tooltip": "Canvia el nombre de columnes"
},
"form": {
"date": {
"label": "Data"
},
"description": {
"label": "Descripció"
},
"email": {
"label": "Correu electrònic"
},
"end-date": {
"help-text": "Deixeu aquest camp en blanc, si encara està present",
"label": "Data de finalització"
},
"keywords": {
"label": "Paraules clau"
},
"level": {
"label": "Nivell"
},
"levelNum": {
"label": "Nivell (nombre)"
},
"name": {
"label": "Nom"
},
"phone": {
"label": "Número de telèfon"
},
"position": {
"label": "Posició"
},
"start-date": {
"label": "Data d'inici"
},
"subtitle": {
"label": "Subtítol"
},
"summary": {
"label": "Resum"
},
"title": {
"label": "Títol"
},
"url": {
"label": "Pàgina web"
}
},
"glossary": {
"page": "Pàgina"
},
"list": {
"actions": {
"delete": "Elimina",
"duplicate": "Duplica",
"edit": "Edita"
},
"empty-text": "Aquesta llista està buida."
},
"tooltip": {
"delete-item": "Estàs segur que vols esborrar aquest element? Aquesta acció és irreversible.",
"delete-section": "Suprimeix una secció",
"rename-section": "Canvia el nom de la secció",
"toggle-visibility": "Commuta la visibilitat"
}
},
"controller": {
"tooltip": {
"center-artboard": "Centrar tauler de dibuix",
"copy-link": "Copia l'enllaç al currículum",
"export-pdf": "Exporta com a PDF",
"toggle-orientation": "Commuta l'orientació de la pàgina",
"toggle-page-break-line": "Commuta la línia de salt de pàgina",
"toggle-sidebars": "Mostra o oculta la barra lateral",
"zoom-in": "Amplia",
"zoom-out": "Allunya",
"undo": "Desfer",
"redo": "Refer"
}
},
"header": {
"menu": {
"delete": "Elimina",
"duplicate": "Duplica",
"rename": "Canvia el nom",
"share-link": "Comparteix l'enllaç",
"tooltips": {
"delete": "Estàs segur que vols esborrar aquest currículum? Aquesta acció és irreversible.",
"share-link": "Heu de canviar la visibilitat del vostre currículum a pública per fer-lo visible per als altres."
}
}
},
"leftSidebar": {
"sections": {
"awards": {
"form": {
"awarder": {
"label": "Otorgat per"
}
}
},
"basics": {
"actions": {
"photo-filters": "Filtres fotogràfics"
},
"heading": "Bàsics",
"headline": {
"label": "Títol"
},
"name": {
"label": "Nom complet"
},
"birthdate": {
"label": "Data de naixement"
},
"photo-filters": {
"effects": {
"border": {
"label": "Vora"
},
"grayscale": {
"label": "Escala de grisos"
},
"heading": "Efectes"
},
"shape": {
"heading": "Forma"
},
"size": {
"heading": "Mida (en px)"
}
},
"photo-upload": {
"tooltip": {
"remove": "Esborrar foto",
"upload": "Pugeu la foto"
}
}
},
"certifications": {
"form": {
"issuer": {
"label": "Emissor"
}
}
},
"education": {
"form": {
"area-study": {
"label": "Àrea d'estudi"
},
"courses": {
"label": "Cursos"
},
"degree": {
"label": "Graus"
},
"grade": {
"label": "Qualificació"
},
"institution": {
"label": "Institució"
}
}
},
"location": {
"address": {
"label": "Adreça"
},
"city": {
"label": "Ciutat"
},
"country": {
"label": "País"
},
"heading": "Ubicació",
"postal-code": {
"label": "Codi Postal"
},
"region": {
"label": "Regió"
}
},
"profiles": {
"form": {
"network": {
"label": "Xarxa"
},
"username": {
"label": "Nom d'usuari"
}
},
"heading": "Perfils",
"heading_one": "Perfil"
},
"publications": {
"form": {
"publisher": {
"label": "Editor"
}
}
},
"references": {
"form": {
"relationship": {
"label": "Relació"
}
}
},
"section": {
"heading": "Secció"
},
"volunteer": {
"form": {
"organization": {
"label": "Organització"
}
}
}
}
},
"rightSidebar": {
"sections": {
"css": {
"heading": "CSS personalitzat"
},
"export": {
"heading": "Exporta",
"json": {
"primary": "JSON",
"secondary": "Baixeu una versió JSON del vostre currículum que es pot tornar a importar a Reactive Resume."
},
"pdf": {
"loading": {
"primary": "Generació de PDF",
"secondary": "Si us plau, espereu mentre es generi el vostre PDF; això pot trigar fins a 15 segons."
},
"normal": {
"primary": "PDF",
"secondary": "Descarrega un PDF del teu currículum que pots imprimir i enviar a la feina dels teus somnis. Aquest fitxer no es pot tornar a importar per editar-lo més."
}
}
},
"layout": {
"heading": "Disseny",
"tooltip": {
"reset-layout": "Restableix el disseny"
}
},
"links": {
"bugs-features": {
"body": "Alguna cosa t'impedeix fer un currículum? O tens una idea sorprenent per afegir? Planteja un problema a GitHub per començar.",
"button": "Problemes de GitHub",
"heading": "Errors? Sol·licituds de funcions?"
},
"donate": {
"body": "Si us ha agradat utilitzar Reactive Resume, considereu donar tant com pugueu per mantenir l'aplicació en funcionament, sense anuncis i gratuïta per sempre.",
"button": "Compra'm un cafè",
"heading": "Dona a Reactive Curriculum vitae"
},
"github": "Codi font",
"docs": "Documentació",
"heading": "Enllaços"
},
"settings": {
"global": {
"date": {
"primary": "Data",
"secondary": "Format de data per utilitzar a l'aplicació"
},
"heading": "Global",
"language": {
"primary": "Llenguatge",
"secondary": "Mostra l'idioma per utilitzar a l'aplicació"
},
"theme": {
"primary": "Tema"
}
},
"heading": "Configuració",
"page": {
"break-line": {
"primary": "Línia de trencament",
"secondary": "Mostra una línia a totes les pàgines per marcar l'alçada d'una pàgina A4"
},
"heading": "Pàgina",
"orientation": {
"disabled": "No té efecte quan només hi ha una pàgina",
"primary": "Orientació",
"secondary": "Si voleu mostrar les pàgines horitzontalment o verticalment"
}
},
"resume": {
"heading": "Resum",
"reset": {
"primary": "Restablir-ho tot",
"secondary": "S'ha equivocat massa? Feu clic aquí per restablir tots els canvis i començar des de zero. Aneu amb compte, aquesta acció no es pot revertir."
},
"sample": {
"primary": "Carregueu dades de mostra",
"secondary": "No saps per on començar? Feu clic aquí per carregar algunes dades de mostra per veure com es veu un currículum complet."
}
}
},
"sharing": {
"heading": "Compartint",
"short-url": {
"label": "Prefereix URL curt"
},
"visibility": {
"subtitle": "Permet que qualsevol persona amb un enllaç vegi el teu currículum",
"title": "Públic"
}
},
"templates": {
"heading": "Plantilles"
},
"theme": {
"form": {
"background": {
"label": "Fons"
},
"primary": {
"label": "primària"
},
"text": {
"label": "Text"
}
},
"heading": "Tema"
},
"typography": {
"form": {
"font-family": {
"label": "Família de lletres"
},
"font-size": {
"label": "Mida de la font"
}
},
"heading": "Tipografia",
"widgets": {
"body": {
"label": "Cos"
},
"headings": {
"label": "Encapçalaments"
}
}
}
}
}
}

View File

@ -0,0 +1,29 @@
{
"avatar": {
"menu": {
"greeting": "Hola",
"logout": "Tancar sessió"
}
},
"footer": {
"credit": "Un projecte de passió d'<1>Amruth Pillai</1>",
"license": "Per la comunitat, per a la comunitat."
},
"markdown": {
"help-text": "Aquesta secció admet <1>reducció</1> formatació."
},
"date": {
"present": "Present"
},
"subtitle": "Un creador de currículums gratuït i de codi obert.",
"title": "Currículum reactiu",
"toast": {
"error": {
"upload-file-size": "Pengeu només fitxers de menys de 2 megabytes.",
"upload-photo-size": "Pengeu només fotos de menys de 2 megabytes, preferiblement quadrades."
},
"success": {
"resume-link-copied": "S'ha copiat un enllaç al vostre currículum al porta-retalls."
}
}
}

View File

@ -0,0 +1,25 @@
{
"create-resume": {
"subtitle": "Començar de zero",
"title": "Crea un currículum nou"
},
"import-external": {
"subtitle": "LinkedIn, currículum JSON, currículum reactiu",
"title": "Importa des de fonts externes"
},
"resume": {
"menu": {
"delete": "Suprimeix",
"duplicate": "Duplicat",
"open": "Obert",
"rename": "Canvia el nom",
"share-link": "Compartir Enllaç",
"tooltips": {
"delete": "Esteu segur que voleu suprimir aquest currículum? Aquesta és una acció irreversible.",
"share-link": "Heu de canviar la visibilitat del vostre currículum a pública per fer-lo visible per als altres."
}
},
"timestamp": "Última actualització fa {{timestamp}}"
},
"title": "panell"
}

View File

@ -0,0 +1,42 @@
{
"actions": {
"app": "Vés a l'aplicació",
"login": "iniciar Sessió",
"logout": "Tancar sessió",
"register": "Registra't"
},
"features": {
"heading": "Característiques",
"list": {
"ads": "No hi ha publicitat",
"export": "Exporteu el vostre currículum a format JSON o PDF",
"free": "Lliure, per sempre",
"import": "Importeu dades de LinkedIn, Currículum JSON",
"languages": "Accessible en diversos idiomes",
"more": "I moltes més funcions interessants, <1>llegiu-ne tot aquí</1>",
"tracking": "Sense seguiment d'usuaris"
}
},
"links": {
"heading": "Enllaços",
"links": {
"donate": "Donar",
"github": "Codi font",
"docs": "Documentació",
"privacy": "Política de privacitat",
"service": "Termes del servei"
}
},
"screenshots": {
"heading": "Captures de pantalla"
},
"testimonials": {
"heading": "Testimonis",
"body": "Bo o dolent, m'encantaria saber la teva opinió sobre Reactive Curriculum vitae i com ha estat l'experiència per a tu.<br/>Aquests són alguns dels missatges enviats pels usuaris de tot el món.",
"contact": "Podeu posar-vos en contacte amb mi mitjançant <1>el meu correu electrònic</1> o mitjançant el formulari de contacte al <3>el meu lloc web</3> ."
},
"summary": {
"body": "Reactive Resume és un creador de currículums gratuït i de codi obert que s'ha creat per fer que les tasques mundanes de crear, actualitzar i compartir el vostre currículum siguin tan fàcils com 1, 2, 3. Amb aquesta aplicació, podeu crear diversos currículums, compartir-los amb reclutadors o amics. mitjançant un enllaç únic i imprimiu-lo com a PDF, tot de franc, sense anuncis, sense seguiment, sense perdre la integritat i la privadesa de les vostres dades.",
"heading": "Resum"
}
}

View File

@ -0,0 +1,135 @@
{
"auth": {
"forgot-password": {
"actions": {
"send-email": "Envieu un correu electrònic de restabliment de la contrasenya"
},
"body": "Només cal que introduïu l'adreça de correu electrònic associada al compte que voleu recuperar.",
"form": {
"email": {
"label": "Correu electrònic"
}
},
"heading": "Has oblidat la teva contrasenya?",
"help-text": "Si el compte existeix, rebràs un correu electrònic amb un enllaç per restablir la teva contrasenya."
},
"login": {
"actions": {
"login": "iniciar Sessió"
},
"body": "Introduïu el vostre nom d'usuari i contrasenya associats al vostre compte per iniciar sessió i accedir, gestionar i compartir els vostres currículums.",
"form": {
"password": {
"label": "Contrasenya"
},
"username": {
"help-text": "També podeu introduir la vostra adreça de correu electrònic",
"label": "Nom d'usuari"
}
},
"heading": "Inicieu sessió al vostre compte",
"recover-text": "En cas que hagis oblidat la teva contrasenya, pots <1>recuperar el teu compte</1> aquí.",
"register-text": "Si no en teniu cap, podeu <1>crear un compte</1> aquí."
},
"register": {
"actions": {
"register": "Registra't",
"google": "Registra't a Google"
},
"body": "Introduïu la vostra informació personal per crear un compte.",
"form": {
"confirm-password": {
"label": "Confirma la contrassenya"
},
"email": {
"label": "Correu electrònic"
},
"name": {
"label": "Nom complet"
},
"password": {
"label": "Contrasenya"
},
"username": {
"label": "Nom d'usuari"
}
},
"heading": "Crear un compte",
"loginText": "Si ja teniu un compte, podeu <1>iniciar sessió aquí</1> ."
},
"reset-password": {
"actions": {
"set-password": "Estableix una contrasenya nova"
},
"body": "Introduïu una contrasenya nova per al vostre compte.",
"form": {
"confirm-password": {
"label": "Confirma la contrassenya"
},
"password": {
"label": "Contrasenya"
}
},
"heading": "Restablir la contrasenya"
}
},
"dashboard": {
"create-resume": {
"actions": {
"create-resume": "Crea un currículum"
},
"body": "Comenceu a crear el vostre currículum posant-li un nom. Pot ser en referència a la funció que esteu sol·licitant, o només al vostre berenar preferit.",
"form": {
"name": {
"label": "Nom"
},
"public": {
"label": "És accessible públicament?"
},
"slug": {
"label": "Llimac"
}
},
"heading": "Crea un currículum nou"
},
"import-external": {
"heading": "Importa des de fonts externes",
"json-resume": {
"actions": {
"upload-json": "Carregueu JSON"
},
"body": "Si teniu un currículum JSON <1>validat</1> a punt per començar, podeu utilitzar-lo per accelerar el vostre desenvolupament a Reactive Resume. Feu clic al botó següent i carregueu un fitxer JSON vàlid per començar.",
"heading": "Importa des del currículum JSON"
},
"linkedin": {
"actions": {
"upload-archive": "Carregueu l'arxiu ZIP"
},
"body": "Podeu estalviar temps exportant les vostres dades de LinkedIn i utilitzant-les per omplir automàticament els camps de Reactive Resume. Aneu a <1>Privadesa de dades</1> secció a LinkedIn i sol·liciteu un arxiu de les vostres dades. Un cop estigui disponible, carregueu el fitxer ZIP a continuació.",
"heading": "Importa des de LinkedIn"
},
"reactive-resume": {
"actions": {
"upload-json": "Carregueu JSON",
"upload-json-v2": "Carregueu JSON des de la v2"
},
"body": "Si teniu un JSON que s'ha exportat amb la versió actual de Reactive Resume, podeu tornar-lo a importar aquí per tornar a obtenir una versió editable.",
"heading": "Importa des del currículum reactiu"
}
},
"rename-resume": {
"actions": {
"rename-resume": "Canvia el nom del currículum"
},
"form": {
"name": {
"label": "Nom"
},
"slug": {
"label": "Llimac"
}
},
"heading": "Canvieu el nom del vostre currículum"
}
}
}

View File

@ -84,7 +84,9 @@
"toggle-page-break-line": "Přepnout řádek zalomení stránky",
"toggle-sidebars": "Přepnout boční panely",
"zoom-in": "Přiblížit",
"zoom-out": "Oddálit"
"zoom-out": "Oddálit",
"undo": "Zrušit",
"redo": "Přepracovat"
}
},
"header": {
@ -119,6 +121,9 @@
"name": {
"label": "Celé jméno"
},
"birthdate": {
"label": "Datum narození"
},
"photo-filters": {
"effects": {
"border": {
@ -265,6 +270,7 @@
"heading": "Přispějte na Reactive Resume"
},
"github": "Zdrojový kód",
"docs": "Dokumentace",
"heading": "Odkazy"
},
"settings": {

View File

@ -0,0 +1,29 @@
{
"avatar": {
"menu": {
"greeting": "Dobrý den",
"logout": "Odhlásit se"
}
},
"footer": {
"credit": "Vášnivý projekt <1>Amrutha Pillaie</1>",
"license": "Od komunity, pro komunitu."
},
"markdown": {
"help-text": "Tato sekce podporuje <1>markdown</1> formátování."
},
"date": {
"present": "Současnost"
},
"subtitle": "Bezplatný a open source tvůrce životopisů.",
"title": "Reactive Resume",
"toast": {
"error": {
"upload-file-size": "Prosím nahrajte pouze soubory pod 2 megabajty.",
"upload-photo-size": "Nahrávejte prosím pouze fotografie o velikosti do 2 megabajtů, nejlépe čtvercové."
},
"success": {
"resume-link-copied": "Odkaz na váš životopis byl zkopírován do schránky."
}
}
}

Some files were not shown because too many files have changed in this diff Show More