Commit db7bc3bd authored by Zakhar Shulha's avatar Zakhar Shulha
Browse files

structure: created main folders and files. in progress fixing errors

parent 97c479b2
......@@ -109,5 +109,6 @@ module.exports = {
'jest/no-identical-title': 'error',
'jest/prefer-to-have-length': 'warn',
'jest/valid-expect': 'error',
'default-param-last': 0,
},
};
import React from 'react';
import './App.css';
import { ConnectedRouter } from 'connected-react-router';
import { Provider } from 'react-redux';
import './styles/index.scss';
import store, { history } from './store';
import ContextProvider from './context';
import Routes from './routes';
import configFile from './config.json';
export default function App(): JSX.Element {
document.title = configFile.displayName;
function App() {
return (
<div className="App">
<header className="App-header">
<p>
Edit
{' '}
<code>src/App.tsx</code>
{' '}
and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
<Provider store={store}>
<ConnectedRouter history={history}>
<ContextProvider>
<Routes />
</ContextProvider>
</ConnectedRouter>
</Provider>
);
}
export default App;
......@@ -18,12 +18,29 @@ interface Alert {
margin?: boolean;
marginTop?: boolean;
marginBottom?: boolean;
content: React.ReactNode | React.ReactNode[];
// content: React.ReactNode | React.ReactNode[];
content: JSX.Element | string;
onClose?: undefined | (() => Action | void);
useActionClose?: string | string[];
dispatchClose: (actionName: string) => Action;
}
interface SelectIcon {
icon: 'success' | 'error' | 'primary' | 'warning' | 'default' | undefined;
type: 'success' | 'error' | 'primary' | 'warning' | 'default' | undefined;
}
function SelectIcon({ icon = undefined, type = undefined }: SelectIcon): JSX.Element | null {
switch (icon || type) {
case 'success': return <RiCheckLine />;
case 'error': return <RiCloseLine />;
case 'primary': return <RiCheckLine />;
case 'warning': return <RiSpam2Line />;
case 'default': return <RiInformationLine />;
default: return null;
}
}
function Alert({
className,
transparent,
......@@ -45,17 +62,6 @@ function Alert({
return null;
}
const SelectIcon = (): JSX.Element | null => {
switch (icon || type) {
case 'success': return <RiCheckLine />;
case 'error': return <RiCloseLine />;
case 'primary': return <RiCheckLine />;
case 'warning': return <RiSpam2Line />;
case 'default': return <RiInformationLine />;
default: return null;
}
};
return (
<div className={clsx(
'alert',
......@@ -71,22 +77,25 @@ function Alert({
>
<div className={styles.wrp}>
<div className={styles.icon}>
<SelectIcon />
<SelectIcon icon={icon} type={type} />
</div>
{Array.isArray(content) ? content.map((value) => {
const list = Object.keys(value as {[key: string]: string});
{/* {Array.isArray(content) ? content.map((value) => { */}
{/* const list = Object.keys(value as unknown as {[key: string]: string;});
// value as {[key: string]: string;} */}
if (list && list.length) {
return list.map((name) => (
<div key={name}>
{list.length > 1 ? `${name}: ` : ''}
{(value as {[key: string]: string})[name]}
</div>
));
}
{/* if (list && list.length) { */}
{/* return list.map((name) => ( */}
{/* <div key={name}> */}
{/* {list.length > 1 ? `${name}: ` : ''} */}
{/* {(value as unknown as {[key: string]: string;})[name]} */}
{/* /!* (value as {[key: string]: string;} *!/ */}
{/* </div> */}
{/* )); */}
{/* } */}
return '';
}) : content}
{/* return ''; */}
{/* }) : content} */}
{content}
</div>
{useBtnClose ? (
<button
......
import React from 'react';
import clsx from 'clsx';
import { useRouteMatch } from 'react-router-dom';
import { Link } from 'react-router-dom';
import { RiCoinLine } from 'react-icons/ri';
import Home from '../../../../../pages/home';
// import Blog from '../../../../../pages/blog';
......@@ -17,8 +17,6 @@ interface Menu {
}
function Menu({ className, list }: Menu): JSX.Element | null {
const match = useRouteMatch();
if (!list) {
return null;
}
......@@ -26,13 +24,13 @@ function Menu({ className, list }: Menu): JSX.Element | null {
return (
<div className={clsx(styles.main, className)}>
{list.map((item) => (
<a
<Link
key={item.to}
href={item.to}
className={match.path === item.to ? styles.linkActive : ''}
to={item.to}
// className={match.path === item.to ? styles.linkActive : ''}
>
{item.name}
</a>
</Link>
))}
</div>
);
......@@ -41,7 +39,6 @@ function Menu({ className, list }: Menu): JSX.Element | null {
export const MenuRoutes = [
{
bind: {
exact: true,
path: 'https://www.budgetsimple.com',
component: Home,
},
......
......@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { RiEyeFill, RiEyeOffFill } from 'react-icons/ri';
import clsx from 'clsx';
import { NavLink, useHistory, useLocation } from 'react-router-dom';
import { NavLink, useNavigate, useLocation } from 'react-router-dom';
import {
Formik, Field, Form, FormikProps,
} from 'formik';
......@@ -36,7 +36,7 @@ interface Content {
interface LoginForm {
email: string;
password: string;
isStaySignedIn: boolean;
rememberMe: boolean;
}
const SignInSchema = Yup.object().shape(validations.signIn);
......@@ -45,27 +45,15 @@ function Content({
signIn, loading, authorized, response, user, error,
}: Content): JSX.Element | null {
const [isViewPassword, setViewPassword] = useState(false);
const history = useHistory();
const navigate = useNavigate();
const location = useLocation();
const { email } = getListLocationParams(location);
const getRedirect = (): string => {
if (user?.onboarding_step && user.onboarding_step >= 5) {
if ((!(user?.subscribed || user?.trial_is_active)) || user.payment_failed !== null) {
return '/plan';
}
return '/dashboard';
}
return '/budget';
};
useEffect(() => {
if (response === null && authorized && user && error === null && !loading) {
history.replace(getRedirect());
if (authorized) {
navigate('/', { replace: true });
}
}, [response, authorized, user, error, loading, history]);
}, [authorized]);
return (
<>
......@@ -74,7 +62,7 @@ function Content({
) : null}
{error ? (
<Alert type="error" content={error.message} useActionClose={SIGN_IN_ERROR_RESET} />
<Alert type="success" content={error.message ? `${error.message}` : ''} useActionClose={SIGN_IN_ERROR_RESET} />
) : null}
<div className={styles.content}>
......@@ -83,20 +71,19 @@ function Content({
initialValues={{
email: email ? email[0] : '',
password: '',
isStaySignedIn: false,
rememberMe: false,
}}
validationSchema={SignInSchema}
onSubmit={(values: LoginForm) => {
signIn({
email: values.email,
password: values.password,
saveState: values.isStaySignedIn,
saveState: values.rememberMe,
});
}}
className={styles.formLogin}
>
{/* eslint-disable-next-line */}
{({ errors, touched, dirty, isValid }: FormikProps<any>) => (
{({ errors, touched, dirty, isValid }: FormikProps<LoginForm>) => (
<Form>
<span>Email</span>
<label className={errors.email && touched.email ? 'label-error' : ''}>
......@@ -119,8 +106,8 @@ function Content({
</label>
<div>
<Field id="isStaySignedIn" name="isStaySignedIn" type="checkbox" className={styles.checkbox} />
<label htmlFor="isStaySignedIn" className={styles.checkboxLabel}>
<Field id="rememberMe" name="rememberMe" type="checkbox" className={styles.checkbox} />
<label htmlFor="rememberMe" className={styles.checkboxLabel}>
<span className={styles.checkboxText}>Stay signed in</span>
</label>
</div>
......
{
"name": "budgetsimple",
"displayName": "Budgetsimple",
"pageSize": 15,
"name": "appname",
"displayName": "App name",
"pageSize": 10,
"paginationSize": 6,
"getUserDelay": 2000,
......
import React, { createContext, useState } from 'react';
import React, { createContext, useMemo, useState } from 'react';
export const Context = createContext({
menu: {
......@@ -14,15 +14,22 @@ interface ContextProvider {
export default function ContextProvider({ children }: ContextProvider): JSX.Element {
const [isOpenMenu, setStateOpenMenu] = useState(false);
const providerValue = useMemo(() => ({
menu: {
isOpen: isOpenMenu,
setStateOpen: setStateOpenMenu,
},
}), [isOpenMenu, setStateOpenMenu]);
return (
<Context.Provider
value={{
menu: {
isOpen: isOpenMenu,
setStateOpen: setStateOpenMenu,
},
}}
value={providerValue}
// value={{
// menu: {
// isOpen: isOpenMenu,
// setStateOpen: setStateOpenMenu,
// },
// }}
>
{children}
</Context.Provider>
......
import React from 'react';
import Content from '../../components/Pages/SignIn';
import { displayName } from '../../config.json';
import configFile from '../../config.json';
import Simple from '../../components/Layout/Landing';
// import Header from '../../components/Common/Header';
import HeaderLogo from '../../components/Layout/Landing/Header/Logo';
......@@ -8,18 +8,17 @@ import HeaderLogo from '../../components/Layout/Landing/Header/Logo';
import useGoogleAnalytics from '../../hooks/googleAnalytics';
export default function Auth(): JSX.Element {
document.title = `${displayName}: Sign In`;
useGoogleAnalytics('Sign In');
document.title = `${configFile.displayName}: Sign In`;
return (
<Simple>
{/*<Header*/}
{/* leftComponent={<HeaderLogo />}*/}
{/*/>*/}
{/*<ContentGrid>*/}
{/* <Content />*/}
{/*</ContentGrid>*/}
<div>Simple Auth component here</div>
{/* <Header */}
{/* leftComponent={<HeaderLogo />} */}
{/* /> */}
{/* <ContentGrid> */}
{/* <Content /> */}
{/* </ContentGrid> */}
</Simple>
);
}
......@@ -6,24 +6,24 @@ import Layout from '../../components/Layout/Landing';
// import Content from '../../components/Pages/ChangeEmail';
import HeaderMenu, { listRoutes } from '../../components/Layout/Landing/Header/Menu';
import HeaderLogo from '../../components/Layout/Landing/Header/Logo';
import { displayName } from '../../config.json';
import configFile from '../../config.json';
import useGoogleAnalytics from '../../hooks/googleAnalytics';
export default function ChangeEmail(): JSX.Element {
document.title = `${displayName}: Change email`;
document.title = `${configFile.displayName}: Change email`;
useGoogleAnalytics('Change email');
return (
<Layout>
{/*<Menu list={listRoutes} simpleLink />*/}
{/*<Header*/}
{/* leftComponent={<HeaderLogo />}*/}
{/* rightComponent={<HeaderMenu />}*/}
{/*/>*/}
{/*<ContentGrid>*/}
{/* /!* <Content /> *!/*/}
{/*</ContentGrid>*/}
{/* <Menu list={listRoutes} simpleLink /> */}
{/* <Header */}
{/* leftComponent={<HeaderLogo />} */}
{/* rightComponent={<HeaderMenu />} */}
{/* /> */}
{/* <ContentGrid> */}
{/* /!* <Content /> *!/ */}
{/* </ContentGrid> */}
</Layout>
);
}
......@@ -6,24 +6,24 @@ import Layout from '../../components/Layout/Landing';
// import Content from '../../components/Pages/ConfirmEmail';
import HeaderMenu, { listRoutes } from '../../components/Layout/Landing/Header/Menu';
import HeaderLogo from '../../components/Layout/Landing/Header/Logo';
import { displayName } from '../../config.json';
import configFile from '../../config.json';
import useGoogleAnalytics from '../../hooks/googleAnalytics';
export default function ConfirmEmail(): JSX.Element {
document.title = `${displayName}: Email confirmed successfully`;
document.title = `${configFile.displayName}: Email confirmed successfully`;
useGoogleAnalytics('Email confirmed successfully');
return (
<Layout>
{/*<Menu list={listRoutes} simpleLink />*/}
{/*<Header*/}
{/* leftComponent={<HeaderLogo />}*/}
{/* rightComponent={<HeaderMenu />}*/}
{/*/>*/}
{/*<ContentGrid>*/}
{/* /!* <Content /> *!/*/}
{/*</ContentGrid>*/}
{/* <Menu list={listRoutes} simpleLink /> */}
{/* <Header */}
{/* leftComponent={<HeaderLogo />} */}
{/* rightComponent={<HeaderMenu />} */}
{/* /> */}
{/* <ContentGrid> */}
{/* /!* <Content /> *!/ */}
{/* </ContentGrid> */}
</Layout>
);
}
import React from 'react';
import { useHistory } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { connect } from 'react-redux';
import Layout from '../../components/Layout/Dashboard';
// import Header from '../../components/Common/Header';
......@@ -25,7 +25,7 @@ import Layout from '../../components/Layout/Dashboard';
// import ByTransactions from '../../components/Pages/Dashboard/Table/ByTransactions';
// import Card from '../../components/Pages/Dashboard/Card';
// import MonthYear from '../../components/Common/SelectDate/MonthYear';
import { displayName } from '../../config.json';
import configFile from '../../config.json';
import { RootState } from '../../store/reducers';
import { moduleName, User } from '../../store/ducks/auth';
import useGoogleAnalytics from '../../hooks/googleAnalytics';
......@@ -36,14 +36,14 @@ interface Dashboard {
}
function Dashboard({ user }: Dashboard): JSX.Element {
document.title = `${displayName}: Dashboard`;
document.title = `${configFile.displayName}: Dashboard`;
useGoogleAnalytics('Dashboard');
const history = useHistory();
const navigate = useNavigate();
if (user && ((!user?.subscribed && !user?.trial_is_active) || user.payment_failed !== null)) {
history.push('/plan');
navigate('/plan');
}
return (
......
import React from 'react';
import { Redirect } from 'react-router-dom';
import { displayName } from '../../config.json';
import { Navigate, Route } from 'react-router-dom';
import configFile from '../../config.json';
export default function Home(): JSX.Element {
document.title = displayName;
document.title = configFile.displayName;
return <Redirect to="/sign-in" />;
// return <Route path="*" element={<Navigate to="/sign-in" replace />} />;
// return (
// <Layout>
......@@ -19,4 +19,8 @@ export default function Home(): JSX.Element {
// </ContentGrid>
// </Layout>
// );
return (
<div>Home!</div>
);
}
......@@ -6,24 +6,24 @@ import Layout from '../../components/Layout/Landing';
// import Content from '../../components/Pages/NewPassword';
import HeaderMenu, { listRoutes } from '../../components/Layout/Landing/Header/Menu';
import HeaderLogo from '../../components/Layout/Landing/Header/Logo';
import { displayName } from '../../config.json';
import configFile from '../../config.json';
import useGoogleAnalytics from '../../hooks/googleAnalytics';
export default function NewPassword(): JSX.Element {
document.title = `${displayName}: New Password`;
document.title = `${configFile.displayName}: New Password`;
useGoogleAnalytics('New Password');
return (
<Layout>
{/*<Menu list={listRoutes} simpleLink />*/}
{/*<Header*/}
{/* leftComponent={<HeaderLogo />}*/}
{/* rightComponent={<HeaderMenu />}*/}
{/*/>*/}
{/*<ContentGrid>*/}
{/* /!* <Content /> *!/*/}
{/*</ContentGrid>*/}
{/* <Menu list={listRoutes} simpleLink /> */}
{/* <Header */}
{/* leftComponent={<HeaderLogo />} */}
{/* rightComponent={<HeaderMenu />} */}
{/* /> */}
{/* <ContentGrid> */}
{/* /!* <Content /> *!/ */}
{/* </ContentGrid> */}
</Layout>
);
}
......@@ -3,27 +3,26 @@ import Layout from '../../components/Layout/Landing';
// import Menu from '../../components/Common/Menu';
// import Header from '../../components/Common/Header';
// import ContentGrid from '../../components/Common/ContentGrid';
import Content from '../../components/Pages/SignIn';
import HeaderMenu, { listRoutes } from '../../components/Layout/Landing/Header/Menu';
import HeaderLogo from '../../components/Layout/Landing/Header/Logo';
import { displayName } from '../../config.json';
import SignInForm from '../../components/Pages/SignIn';
import configFile from '../../config.json';
import useGoogleAnalytics from '../../hooks/googleAnalytics';
export default function SignIn(): JSX.Element {
document.title = `${displayName}: Sign in`;
document.title = `${configFile.displayName}: Sign in`;
useGoogleAnalytics('Sign In');
return (
<Layout>
{/*<Menu list={listRoutes} simpleLink />*/}
{/*<Header*/}
{/* leftComponent={<HeaderLogo />}*/}
{/* rightComponent={<HeaderMenu />}*/}
{/*/>*/}
{/*<ContentGrid>*/}
{/* <Content />*/}
{/*</ContentGrid>*/}
<SignInForm />
{/* <Menu list={listRoutes} simpleLink /> */}
{/* <Header */}
{/* leftComponent={<HeaderLogo />} */}
{/* rightComponent={<HeaderMenu />} */}
{/* /> */}
{/* <ContentGrid> */}
{/* <Content /> */}
{/* </ContentGrid> */}
</Layout>
);