mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-14 00:32:35 +10:00
experiments with docker packaging, figuring out deploy plan
This commit is contained in:
@ -1,2 +1,8 @@
|
||||
NEXT_PUBLIC_APP_VERSION=$npm_package_version
|
||||
|
||||
# App & Server URLs
|
||||
NEXT_PUBLIC_APP_URL=$APP_URL
|
||||
NEXT_PUBLIC_SERVER_URL=$SERVER_URL
|
||||
|
||||
# Google OAuth
|
||||
NEXT_PUBLIC_GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID
|
||||
18
apps/client/i18n/index.ts
Normal file
18
apps/client/i18n/index.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import HttpBackend from 'i18next-http-backend';
|
||||
|
||||
const i18nConfig = {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
debug: false,
|
||||
nsSeparator: '.',
|
||||
ns: ['common', 'modals', 'landing', 'dashboard', 'builder'],
|
||||
serializeConfig: false,
|
||||
use: [HttpBackend],
|
||||
backend: {
|
||||
loadPath: `${process.env.NEXT_PUBLIC_APP_URL}/locales/{{lng}}/{{ns}}.json`,
|
||||
},
|
||||
};
|
||||
|
||||
export default i18nConfig;
|
||||
@ -1,14 +0,0 @@
|
||||
/**
|
||||
* @type {import('next-i18next').UserConfig}
|
||||
**/
|
||||
module.exports = {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
debug: false,
|
||||
nsSeparator: '.',
|
||||
initImmediate: false,
|
||||
localePath: './apps/client/public/locales',
|
||||
ns: ['common', 'modals', 'landing', 'dashboard', 'builder'],
|
||||
};
|
||||
@ -1,12 +1,13 @@
|
||||
const withNx = require('@nrwl/next/plugins/with-nx');
|
||||
|
||||
const { i18n } = require('./next-i18next.config');
|
||||
|
||||
/**
|
||||
* @type {import('@nrwl/next/plugins/with-nx').WithNxOptions}
|
||||
**/
|
||||
const nextConfig = {
|
||||
i18n,
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
|
||||
nx: {
|
||||
svgr: false,
|
||||
|
||||
@ -4,11 +4,11 @@ import { GetServerSideProps, NextPage } from 'next';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Head from 'next/head';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import i18nConfig from 'next-i18next.config';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import i18nConfig from '@/i18n/index';
|
||||
import { fetchResumeByIdentifier } from '@/services/resume';
|
||||
import { useAppDispatch } from '@/store/hooks';
|
||||
import { setResume } from '@/store/resume/resumeSlice';
|
||||
|
||||
@ -9,12 +9,12 @@ import { GetServerSideProps, NextPage } from 'next';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import i18nConfig from 'next-i18next.config';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import i18nConfig from '@/i18n/index';
|
||||
import { ServerError } from '@/services/axios';
|
||||
import { printResumeAsPdf, PrintResumeAsPdfParams } from '@/services/printer';
|
||||
import { fetchResumeByIdentifier } from '@/services/resume';
|
||||
@ -39,7 +39,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ query, loc
|
||||
const { username, slug } = query as QueryParams;
|
||||
|
||||
try {
|
||||
const resume = await fetchResumeByIdentifier({ username, slug, options: { withHost: true } });
|
||||
const resume = await fetchResumeByIdentifier({ username, slug });
|
||||
|
||||
return {
|
||||
props: { username, slug, resume, ...(await serverSideTranslations(locale, ['common'], i18nConfig)) },
|
||||
|
||||
@ -31,7 +31,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ query }) =
|
||||
try {
|
||||
if (isEmpty(secretKey)) throw new Error('There is no secret key!');
|
||||
|
||||
const resume = await fetchResumeByIdentifier({ username, slug, options: { secretKey, withHost: true } });
|
||||
const resume = await fetchResumeByIdentifier({ username, slug, options: { secretKey } });
|
||||
|
||||
return { props: { resume } };
|
||||
} catch (error) {
|
||||
|
||||
@ -4,36 +4,28 @@ import DateAdapter from '@mui/lab/AdapterDayjs';
|
||||
import LocalizationProvider from '@mui/lab/LocalizationProvider';
|
||||
import type { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import { appWithTranslation, useTranslation } from 'next-i18next';
|
||||
import i18nConfig from 'next-i18next.config';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { appWithTranslation } from 'next-i18next';
|
||||
import { Toaster } from 'react-hot-toast';
|
||||
import { QueryClientProvider } from 'react-query';
|
||||
import { Provider as ReduxProvider } from 'react-redux';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
|
||||
import Loading from '@/components/shared/Loading';
|
||||
import i18nConfig from '@/i18n/index';
|
||||
import ModalWrapper from '@/modals/index';
|
||||
import queryClient from '@/services/react-query';
|
||||
import store, { persistor } from '@/store/index';
|
||||
import WrapperRegistry from '@/wrappers/index';
|
||||
|
||||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale, ['common', 'modals'], i18nConfig)),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const App: React.FC<AppProps> = ({ Component, pageProps }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{t('common.title')}</title>
|
||||
<meta name="description" content={t('common.description')} />
|
||||
<title>Reactive Resume</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Reactive Resume is a free and open source resume builder that's built to make the mundane tasks of creating, updating and sharing your resume as easy as 1, 2, 3."
|
||||
/>
|
||||
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="initial-scale=1, width=device-width" />
|
||||
|
||||
@ -4,11 +4,11 @@ import dynamic from 'next/dynamic';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import i18nConfig from 'next-i18next.config';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import { RESUMES_QUERY } from '@/constants/index';
|
||||
import i18nConfig from '@/i18n/index';
|
||||
import { fetchResumes } from '@/services/resume';
|
||||
import styles from '@/styles/pages/Dashboard.module.scss';
|
||||
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { Link as LinkIcon } from '@mui/icons-material';
|
||||
import { Button } from '@mui/material';
|
||||
import type { NextPage } from 'next';
|
||||
import type { GetServerSideProps, NextPage } from 'next';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { Trans, useTranslation } from 'next-i18next';
|
||||
import i18nConfig from 'next-i18next.config';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
|
||||
import { screenshots } from '@/config/screenshots';
|
||||
import i18nConfig from '@/i18n/index';
|
||||
import { logout } from '@/store/auth/authSlice';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { setModalState } from '@/store/modal/modalSlice';
|
||||
@ -20,13 +20,13 @@ const Footer = dynamic(() => import('@/components/shared/Footer'));
|
||||
const Logo = dynamic(() => import('@/components/shared/Logo'));
|
||||
const NoSSR = dynamic(() => import('@/components/shared/NoSSR'));
|
||||
|
||||
export async function getStaticProps({ locale }) {
|
||||
export const getServerSideProps: GetServerSideProps = async ({ locale }) => {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale, ['common', 'modals', 'landing'], i18nConfig)),
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -8,12 +8,12 @@ import isEmpty from 'lodash/isEmpty';
|
||||
import { GetServerSideProps, NextPage } from 'next';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Link from 'next/link';
|
||||
import i18nConfig from 'next-i18next.config';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import i18nConfig from '@/i18n/index';
|
||||
import { ServerError } from '@/services/axios';
|
||||
import { printResumeAsPdf, PrintResumeAsPdfParams } from '@/services/printer';
|
||||
import { fetchResumeByShortId } from '@/services/resume';
|
||||
@ -36,7 +36,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ query, loc
|
||||
const { shortId } = query as QueryParams;
|
||||
|
||||
try {
|
||||
const resume = await fetchResumeByShortId({ shortId, options: { withHost: true } });
|
||||
const resume = await fetchResumeByShortId({ shortId });
|
||||
|
||||
return { props: { shortId, resume, ...(await serverSideTranslations(locale, ['common'], i18nConfig)) } };
|
||||
} catch {
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"/api": {
|
||||
"target": "http://localhost:3100",
|
||||
"secure": false
|
||||
}
|
||||
}
|
||||
@ -13,11 +13,11 @@ export type ServerError = {
|
||||
};
|
||||
|
||||
const axios = _axios.create({
|
||||
baseURL: '/api',
|
||||
baseURL: `${process.env.NEXT_PUBLIC_SERVER_URL}/api`,
|
||||
});
|
||||
|
||||
export const uninterceptedAxios = _axios.create({
|
||||
baseURL: '/api',
|
||||
baseURL: `${process.env.NEXT_PUBLIC_SERVER_URL}/api`,
|
||||
});
|
||||
|
||||
axios.interceptors.request.use((config) => {
|
||||
|
||||
@ -14,7 +14,6 @@ export type FetchResumeByIdentifierParams = {
|
||||
username: string;
|
||||
slug: string;
|
||||
options?: {
|
||||
withHost?: boolean;
|
||||
secretKey?: string;
|
||||
};
|
||||
};
|
||||
@ -22,7 +21,6 @@ export type FetchResumeByIdentifierParams = {
|
||||
export type FetchResumeByShortIdParams = {
|
||||
shortId: string;
|
||||
options?: {
|
||||
withHost?: boolean;
|
||||
secretKey?: string;
|
||||
};
|
||||
};
|
||||
@ -60,25 +58,20 @@ export type DeleteResumeParams = {
|
||||
|
||||
export const fetchResumes = () => axios.get<Resume[]>('/resume').then((res) => res.data);
|
||||
|
||||
export const fetchResumeByShortId = async ({
|
||||
shortId,
|
||||
options = { secretKey: '', withHost: false },
|
||||
}: FetchResumeByShortIdParams) => {
|
||||
const hostname = options.withHost ? `${process.env.SERVER_URL}/api` : '';
|
||||
export const fetchResumeByShortId = async ({ shortId, options = { secretKey: '' } }: FetchResumeByShortIdParams) => {
|
||||
const requestOptions = isEmpty(options.secretKey) ? {} : { params: { secretKey: options.secretKey } };
|
||||
|
||||
return axios.get<Resume>(`${hostname}/resume/short/${shortId}`, requestOptions).then((res) => res.data);
|
||||
return axios.get<Resume>(`/resume/short/${shortId}`, requestOptions).then((res) => res.data);
|
||||
};
|
||||
|
||||
export const fetchResumeByIdentifier = async ({
|
||||
username,
|
||||
slug,
|
||||
options = { secretKey: '', withHost: false },
|
||||
options = { secretKey: '' },
|
||||
}: FetchResumeByIdentifierParams) => {
|
||||
const hostname = options.withHost ? `${process.env.SERVER_URL}/api` : '';
|
||||
const requestOptions = isEmpty(options.secretKey) ? {} : { params: { secretKey: options.secretKey } };
|
||||
|
||||
return axios.get<Resume>(`${hostname}/resume/${username}/${slug}`, requestOptions).then((res) => res.data);
|
||||
return axios.get<Resume>(`/resume/${username}/${slug}`, requestOptions).then((res) => res.data);
|
||||
};
|
||||
|
||||
export const createResume = (createResumeParams: CreateResumeParams) =>
|
||||
|
||||
@ -16,12 +16,13 @@
|
||||
"paths": {
|
||||
"@/components/*": ["components/*"],
|
||||
"@/config/*": ["config/*"],
|
||||
"@/constants/*": ["constants/*"],
|
||||
"@/i18n/*": ["i18n/*"],
|
||||
"@/modals/*": ["modals/*"],
|
||||
"@/pages/*": ["pages/*"],
|
||||
"@/public/*": ["public/*"],
|
||||
"@/services/*": ["services/*"],
|
||||
"@/store/*": ["store/*"],
|
||||
"@/constants/*": ["constants/*"],
|
||||
"@/styles/*": ["styles/*"],
|
||||
"@/templates/*": ["templates/*"],
|
||||
"@/types/*": ["types/*"],
|
||||
|
||||
Reference in New Issue
Block a user