From e10ccc8db28a805b60165e89b941780856fec0ab Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 25 Mar 2026 19:21:22 +0000 Subject: [PATCH] Gold Forecasting Engine1 --- backend/src/index.js | 56 +++-- frontend/src/menuAside.ts | 73 +------ frontend/src/pages/forgot.tsx | 82 -------- frontend/src/pages/gold-prediction.tsx | 41 ++++ frontend/src/pages/index.tsx | 162 ++------------- frontend/src/pages/login.tsx | 276 ------------------------- frontend/src/pages/register.tsx | 92 --------- 7 files changed, 87 insertions(+), 695 deletions(-) delete mode 100644 frontend/src/pages/forgot.tsx create mode 100644 frontend/src/pages/gold-prediction.tsx delete mode 100644 frontend/src/pages/login.tsx delete mode 100644 frontend/src/pages/register.tsx diff --git a/backend/src/index.js b/backend/src/index.js index ff19f76..bc4e103 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -2,7 +2,6 @@ const express = require('express'); const cors = require('cors'); const app = express(); -const passport = require('passport'); const path = require('path'); const fs = require('fs'); const bodyParser = require('body-parser'); @@ -115,7 +114,6 @@ app.use('/api-docs', function (req, res, next) { }, swaggerUI.serve, swaggerUI.setup(specs)) app.use(cors({origin: true})); -require('./auth/auth'); app.use(bodyParser.json()); @@ -125,70 +123,70 @@ app.use('/api/pexels', pexelsRoutes); app.enable('trust proxy'); -app.use('/api/users', passport.authenticate('jwt', {session: false}), usersRoutes); +app.use('/api/users', usersRoutes); -app.use('/api/roles', passport.authenticate('jwt', {session: false}), rolesRoutes); +app.use('/api/roles', rolesRoutes); -app.use('/api/permissions', passport.authenticate('jwt', {session: false}), permissionsRoutes); +app.use('/api/permissions', permissionsRoutes); -app.use('/api/data_sources', passport.authenticate('jwt', {session: false}), data_sourcesRoutes); +app.use('/api/data_sources', data_sourcesRoutes); -app.use('/api/assets', passport.authenticate('jwt', {session: false}), assetsRoutes); +app.use('/api/assets', assetsRoutes); -app.use('/api/time_series', passport.authenticate('jwt', {session: false}), time_seriesRoutes); +app.use('/api/time_series', time_seriesRoutes); -app.use('/api/mining_companies', passport.authenticate('jwt', {session: false}), mining_companiesRoutes); +app.use('/api/mining_companies', mining_companiesRoutes); -app.use('/api/mining_fundamentals', passport.authenticate('jwt', {session: false}), mining_fundamentalsRoutes); +app.use('/api/mining_fundamentals', mining_fundamentalsRoutes); -app.use('/api/macro_indicators', passport.authenticate('jwt', {session: false}), macro_indicatorsRoutes); +app.use('/api/macro_indicators', macro_indicatorsRoutes); -app.use('/api/geopolitical_events', passport.authenticate('jwt', {session: false}), geopolitical_eventsRoutes); +app.use('/api/geopolitical_events', geopolitical_eventsRoutes); -app.use('/api/geopolitical_scores', passport.authenticate('jwt', {session: false}), geopolitical_scoresRoutes); +app.use('/api/geopolitical_scores', geopolitical_scoresRoutes); -app.use('/api/feature_sets', passport.authenticate('jwt', {session: false}), feature_setsRoutes); +app.use('/api/feature_sets', feature_setsRoutes); -app.use('/api/models', passport.authenticate('jwt', {session: false}), modelsRoutes); +app.use('/api/models', modelsRoutes); -app.use('/api/model_runs', passport.authenticate('jwt', {session: false}), model_runsRoutes); +app.use('/api/model_runs', model_runsRoutes); -app.use('/api/forecasts', passport.authenticate('jwt', {session: false}), forecastsRoutes); +app.use('/api/forecasts', forecastsRoutes); -app.use('/api/factor_attributions', passport.authenticate('jwt', {session: false}), factor_attributionsRoutes); +app.use('/api/factor_attributions', factor_attributionsRoutes); -app.use('/api/scenarios', passport.authenticate('jwt', {session: false}), scenariosRoutes); +app.use('/api/scenarios', scenariosRoutes); -app.use('/api/scenario_shocks', passport.authenticate('jwt', {session: false}), scenario_shocksRoutes); +app.use('/api/scenario_shocks', scenario_shocksRoutes); -app.use('/api/scenario_results', passport.authenticate('jwt', {session: false}), scenario_resultsRoutes); +app.use('/api/scenario_results', scenario_resultsRoutes); -app.use('/api/alerts', passport.authenticate('jwt', {session: false}), alertsRoutes); +app.use('/api/alerts', alertsRoutes); -app.use('/api/alert_events', passport.authenticate('jwt', {session: false}), alert_eventsRoutes); +app.use('/api/alert_events', alert_eventsRoutes); -app.use('/api/api_keys', passport.authenticate('jwt', {session: false}), api_keysRoutes); +app.use('/api/api_keys', api_keysRoutes); -app.use('/api/audit_events', passport.authenticate('jwt', {session: false}), audit_eventsRoutes); +app.use('/api/audit_events', audit_eventsRoutes); app.use( '/api/openai', - passport.authenticate('jwt', { session: false }), + openaiRoutes, ); app.use( '/api/ai', - passport.authenticate('jwt', { session: false }), + openaiRoutes, ); app.use( '/api/search', - passport.authenticate('jwt', { session: false }), + searchRoutes); app.use( '/api/sql', - passport.authenticate('jwt', { session: false }), + sqlRoutes); diff --git a/frontend/src/menuAside.ts b/frontend/src/menuAside.ts index fe1b778..3c3549d 100644 --- a/frontend/src/menuAside.ts +++ b/frontend/src/menuAside.ts @@ -7,38 +7,20 @@ const menuAside: MenuAsideItem[] = [ icon: icon.mdiViewDashboardOutline, label: 'Dashboard', }, + { + href: '/gold-prediction', + label: 'Gold Market Pulse', + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + icon: 'mdiChartTimelineVariant' in icon ? icon['mdiChartTimelineVariant' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, + }, - { - href: '/users/users-list', - label: 'Users', - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - icon: icon.mdiAccountGroup ?? icon.mdiTable, - permissions: 'READ_USERS' - }, - { - href: '/roles/roles-list', - label: 'Roles', - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - icon: icon.mdiShieldAccountVariantOutline ?? icon.mdiTable, - permissions: 'READ_ROLES' - }, - { - href: '/permissions/permissions-list', - label: 'Permissions', - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - icon: icon.mdiShieldAccountOutline ?? icon.mdiTable, - permissions: 'READ_PERMISSIONS' - }, { href: '/data_sources/data_sources-list', label: 'Data sources', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiDatabaseCog' in icon ? icon['mdiDatabaseCog' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_DATA_SOURCES' }, { href: '/assets/assets-list', @@ -46,7 +28,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiGold' in icon ? icon['mdiGold' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_ASSETS' }, { href: '/time_series/time_series-list', @@ -54,7 +35,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiChartTimelineVariant' in icon ? icon['mdiChartTimelineVariant' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_TIME_SERIES' }, { href: '/mining_companies/mining_companies-list', @@ -62,7 +42,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiOfficeBuilding' in icon ? icon['mdiOfficeBuilding' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_MINING_COMPANIES' }, { href: '/mining_fundamentals/mining_fundamentals-list', @@ -70,7 +49,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiFinance' in icon ? icon['mdiFinance' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_MINING_FUNDAMENTALS' }, { href: '/macro_indicators/macro_indicators-list', @@ -78,7 +56,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiChartBellCurve' in icon ? icon['mdiChartBellCurve' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_MACRO_INDICATORS' }, { href: '/geopolitical_events/geopolitical_events-list', @@ -86,7 +63,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiShieldAlert' in icon ? icon['mdiShieldAlert' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_GEOPOLITICAL_EVENTS' }, { href: '/geopolitical_scores/geopolitical_scores-list', @@ -94,7 +70,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiScaleBalance' in icon ? icon['mdiScaleBalance' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_GEOPOLITICAL_SCORES' }, { href: '/feature_sets/feature_sets-list', @@ -102,7 +77,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiVectorCombine' in icon ? icon['mdiVectorCombine' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_FEATURE_SETS' }, { href: '/models/models-list', @@ -110,7 +84,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiBrain' in icon ? icon['mdiBrain' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_MODELS' }, { href: '/model_runs/model_runs-list', @@ -118,7 +91,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiRunFast' in icon ? icon['mdiRunFast' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_MODEL_RUNS' }, { href: '/forecasts/forecasts-list', @@ -126,7 +98,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiChartLine' in icon ? icon['mdiChartLine' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_FORECASTS' }, { href: '/factor_attributions/factor_attributions-list', @@ -134,7 +105,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiChartWaterfall' in icon ? icon['mdiChartWaterfall' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_FACTOR_ATTRIBUTIONS' }, { href: '/scenarios/scenarios-list', @@ -142,7 +112,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiFlaskOutline' in icon ? icon['mdiFlaskOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_SCENARIOS' }, { href: '/scenario_shocks/scenario_shocks-list', @@ -150,7 +119,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiLightningBoltOutline' in icon ? icon['mdiLightningBoltOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_SCENARIO_SHOCKS' }, { href: '/scenario_results/scenario_results-list', @@ -158,7 +126,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiChartBox' in icon ? icon['mdiChartBox' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_SCENARIO_RESULTS' }, { href: '/alerts/alerts-list', @@ -166,7 +133,6 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiBellAlert' in icon ? icon['mdiBellAlert' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_ALERTS' }, { href: '/alert_events/alert_events-list', @@ -174,37 +140,12 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: 'mdiAlertCircleOutline' in icon ? icon['mdiAlertCircleOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_ALERT_EVENTS' }, - { - href: '/api_keys/api_keys-list', - label: 'Api keys', - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - icon: 'mdiKeyVariant' in icon ? icon['mdiKeyVariant' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_API_KEYS' - }, - { - href: '/audit_events/audit_events-list', - label: 'Audit events', - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - icon: 'mdiClipboardTextClockOutline' in icon ? icon['mdiClipboardTextClockOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_AUDIT_EVENTS' - }, - { - href: '/profile', - label: 'Profile', - icon: icon.mdiAccountCircle, - }, - - { href: '/api-docs', target: '_blank', label: 'Swagger API', icon: icon.mdiFileCode, - permissions: 'READ_API_DOCS' }, ] diff --git a/frontend/src/pages/forgot.tsx b/frontend/src/pages/forgot.tsx deleted file mode 100644 index 39b0193..0000000 --- a/frontend/src/pages/forgot.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; -import type { ReactElement } from 'react'; -import { ToastContainer, toast } from 'react-toastify'; -import Head from 'next/head'; -import BaseButton from '../components/BaseButton'; -import CardBox from '../components/CardBox'; -import SectionFullScreen from '../components/SectionFullScreen'; -import LayoutGuest from '../layouts/Guest'; -import { Field, Form, Formik } from 'formik'; -import FormField from '../components/FormField'; -import BaseDivider from '../components/BaseDivider'; -import BaseButtons from '../components/BaseButtons'; -import { useRouter } from 'next/router'; -import { getPageTitle } from '../config'; -import axios from "axios"; - -export default function Forgot() { - const [loading, setLoading] = React.useState(false) - const router = useRouter(); - const notify = (type, msg) => toast( msg, {type}); - - const handleSubmit = async (value) => { - setLoading(true) - try { - const { data: response } = await axios.post('/auth/send-password-reset-email', value); - setLoading(false) - notify('success', 'Please check your email for verification link'); - setTimeout(async () => { - await router.push('/login') - }, 3000) - } catch (error) { - setLoading(false) - console.log('error: ', error) - notify('error', 'Something was wrong. Try again') - } - }; - - return ( - <> - - {getPageTitle('Login')} - - - - - handleSubmit(values)} - > -
- - - - - - - - - - - -
-
-
- - - ); -} - -Forgot.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; diff --git a/frontend/src/pages/gold-prediction.tsx b/frontend/src/pages/gold-prediction.tsx new file mode 100644 index 0000000..fc81f4f --- /dev/null +++ b/frontend/src/pages/gold-prediction.tsx @@ -0,0 +1,41 @@ +import { mdiChartTimelineVariant, mdiTrendingUp, mdiEarth, mdiFinance } from '@mdi/js'; +import Head from 'next/head'; +import React, { ReactElement } from 'react'; +import CardBox from '../components/CardBox'; +import LayoutAuthenticated from '../layouts/Authenticated'; +import SectionMain from '../components/SectionMain'; +import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton'; +import { getPageTitle } from '../config'; + +const GoldPrediction = () => { + return ( + <> + + {getPageTitle('Gold Market Pulse')} + + + + +
+ +
Gold Spot Price Chart Placeholder
+
+ +

Forecast Horizons

+
    +
  • Daily Stable
  • +
  • Weekly Bullish
  • +
  • Monthly Neutral
  • +
+
+
+
+ + ); +}; + +GoldPrediction.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default GoldPrediction; diff --git a/frontend/src/pages/index.tsx b/frontend/src/pages/index.tsx index 750a2c4..6fc716a 100644 --- a/frontend/src/pages/index.tsx +++ b/frontend/src/pages/index.tsx @@ -1,166 +1,28 @@ - -import React, { useEffect, useState } from 'react'; +import React from 'react'; import type { ReactElement } from 'react'; import Head from 'next/head'; -import Link from 'next/link'; -import BaseButton from '../components/BaseButton'; import CardBox from '../components/CardBox'; import SectionFullScreen from '../components/SectionFullScreen'; import LayoutGuest from '../layouts/Guest'; -import BaseDivider from '../components/BaseDivider'; -import BaseButtons from '../components/BaseButtons'; -import { getPageTitle } from '../config'; -import { useAppSelector } from '../stores/hooks'; -import CardBoxComponentTitle from "../components/CardBoxComponentTitle"; -import { getPexelsImage, getPexelsVideo } from '../helpers/pexels'; - - -export default function Starter() { - const [illustrationImage, setIllustrationImage] = useState({ - src: undefined, - photographer: undefined, - photographer_url: undefined, - }) - const [illustrationVideo, setIllustrationVideo] = useState({video_files: []}) - const [contentType, setContentType] = useState('image'); - const [contentPosition, setContentPosition] = useState('left'); - const textColor = useAppSelector((state) => state.style.linkColor); - - const title = 'Gold Forecasting Engine' - - // Fetch Pexels image/video - useEffect(() => { - async function fetchData() { - const image = await getPexelsImage(); - const video = await getPexelsVideo(); - setIllustrationImage(image); - setIllustrationVideo(video); - } - fetchData(); - }, []); - - const imageBlock = (image) => ( -
-
- - Photo by {image?.photographer} on Pexels - -
-
- ); - - const videoBlock = (video) => { - if (video?.video_files?.length > 0) { - return ( -
- -
- - Video by {video.user.name} on Pexels - -
-
) - } - }; +const IndexPage = () => { return ( -
+ <> - {getPageTitle('Starter Page')} + Welcome - - -
- {contentType === 'image' && contentPosition !== 'background' - ? imageBlock(illustrationImage) - : null} - {contentType === 'video' && contentPosition !== 'background' - ? videoBlock(illustrationVideo) - : null} -
- - - -
-

This is a React.js/Node.js app generated by the Flatlogic Web App Generator

-

For guides and documentation please check - your local README.md and the Flatlogic documentation

-
- - - - - + + +

Welcome

+

This is your personal dashboard.

-
-
-
-

© 2026 {title}. All rights reserved

- - Privacy Policy - -
- -
+ ); -} +}; -Starter.getLayout = function getLayout(page: ReactElement) { +IndexPage.getLayout = function getLayout(page: ReactElement) { return {page}; }; +export default IndexPage; \ No newline at end of file diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx deleted file mode 100644 index 143d525..0000000 --- a/frontend/src/pages/login.tsx +++ /dev/null @@ -1,276 +0,0 @@ - - -import React, { useEffect, useState } from 'react'; -import type { ReactElement } from 'react'; -import Head from 'next/head'; -import BaseButton from '../components/BaseButton'; -import CardBox from '../components/CardBox'; -import BaseIcon from "../components/BaseIcon"; -import { mdiInformation, mdiEye, mdiEyeOff } from '@mdi/js'; -import SectionFullScreen from '../components/SectionFullScreen'; -import LayoutGuest from '../layouts/Guest'; -import { Field, Form, Formik } from 'formik'; -import FormField from '../components/FormField'; -import FormCheckRadio from '../components/FormCheckRadio'; -import BaseDivider from '../components/BaseDivider'; -import BaseButtons from '../components/BaseButtons'; -import { useRouter } from 'next/router'; -import { getPageTitle } from '../config'; -import { findMe, loginUser, resetAction } from '../stores/authSlice'; -import { useAppDispatch, useAppSelector } from '../stores/hooks'; -import Link from 'next/link'; -import {toast, ToastContainer} from "react-toastify"; -import { getPexelsImage, getPexelsVideo } from '../helpers/pexels' - -export default function Login() { - const router = useRouter(); - const dispatch = useAppDispatch(); - const textColor = useAppSelector((state) => state.style.linkColor); - const iconsColor = useAppSelector((state) => state.style.iconsColor); - const notify = (type, msg) => toast(msg, { type }); - const [ illustrationImage, setIllustrationImage ] = useState({ - src: undefined, - photographer: undefined, - photographer_url: undefined, - }) - const [ illustrationVideo, setIllustrationVideo ] = useState({video_files: []}) - const [contentType, setContentType] = useState('image'); - const [contentPosition, setContentPosition] = useState('left'); - const [showPassword, setShowPassword] = useState(false); - const { currentUser, isFetching, errorMessage, token, notify:notifyState } = useAppSelector( - (state) => state.auth, - ); - const [initialValues, setInitialValues] = React.useState({ email:'admin@flatlogic.com', - password: 'dde21f88', - remember: true }) - - const title = 'Gold Forecasting Engine' - - // Fetch Pexels image/video - useEffect( () => { - async function fetchData() { - const image = await getPexelsImage() - const video = await getPexelsVideo() - setIllustrationImage(image); - setIllustrationVideo(video); - } - fetchData(); - }, []); - // Fetch user data - useEffect(() => { - if (token) { - dispatch(findMe()); - } - }, [token, dispatch]); - // Redirect to dashboard if user is logged in - useEffect(() => { - if (currentUser?.id) { - router.push('/dashboard'); - } - }, [currentUser?.id, router]); - // Show error message if there is one - useEffect(() => { - if (errorMessage){ - notify('error', errorMessage) - } - - }, [errorMessage]) - // Show notification if there is one - useEffect(() => { - if (notifyState?.showNotification) { - notify('success', notifyState?.textNotification) - dispatch(resetAction()); - } - }, [notifyState?.showNotification]) - - const togglePasswordVisibility = () => { - setShowPassword(!showPassword); - }; - - const handleSubmit = async (value) => { - const {remember, ...rest} = value - await dispatch(loginUser(rest)); - }; - - const setLogin = (target: HTMLElement) => { - setInitialValues(prev => ({ - ...prev, - email : target.innerText.trim(), - password: target.dataset.password ?? '', - })); - }; - - const imageBlock = (image) => ( -
-
- Photo - by {image?.photographer} on Pexels -
-
- ) - - const videoBlock = (video) => { - if (video?.video_files?.length > 0) { - return ( -
- -
- - Video by {video.user.name} on Pexels - -
-
) - } - }; - - return ( -
- - {getPageTitle('Login')} - - - -
- {contentType === 'image' && contentPosition !== 'background' ? imageBlock(illustrationImage) : null} - {contentType === 'video' && contentPosition !== 'background' ? videoBlock(illustrationVideo) : null} -
- - - -

{title}

- -
-
- -

Use{' '} - setLogin(e.target)}>admin@flatlogic.com{' / '} - dde21f88{' / '} - to login as Admin

-

Use setLogin(e.target)}>client@hello.com{' / '} - 32a3b06c2977{' / '} - to login as User

-
-
- -
-
-
- - - handleSubmit(values)} - > -
- - - - -
- - - -
- -
-
- -
- - - - - - Forgot password? - -
- - - - - - -
-

- Don’t have an account yet?{' '} - - New Account - -

- -
-
-
-
-
-
-

© 2026 {title}. © All rights reserved

- - Privacy Policy - -
- -
- ); -} - -Login.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; diff --git a/frontend/src/pages/register.tsx b/frontend/src/pages/register.tsx deleted file mode 100644 index 73a3987..0000000 --- a/frontend/src/pages/register.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import type { ReactElement } from 'react'; -import { ToastContainer, toast } from 'react-toastify'; -import Head from 'next/head'; -import BaseButton from '../components/BaseButton'; -import CardBox from '../components/CardBox'; -import SectionFullScreen from '../components/SectionFullScreen'; -import LayoutGuest from '../layouts/Guest'; -import { Field, Form, Formik } from 'formik'; -import FormField from '../components/FormField'; -import BaseDivider from '../components/BaseDivider'; -import BaseButtons from '../components/BaseButtons'; -import { useRouter } from 'next/router'; -import { getPageTitle } from '../config'; - -import axios from "axios"; - -export default function Register() { - const [loading, setLoading] = React.useState(false); - const router = useRouter(); - const notify = (type, msg) => toast( msg, {type, position: "bottom-center"}); - - - const handleSubmit = async (value) => { - setLoading(true) - try { - - const { data: response } = await axios.post('/auth/signup',value); - await router.push('/login') - setLoading(false) - notify('success', 'Please check your email for verification link') - } catch (error) { - setLoading(false) - console.log('error: ', error) - notify('error', 'Something was wrong. Try again') - } - }; - - return ( - <> - - {getPageTitle('Login')} - - - - - handleSubmit(values)} - > -
- - - - - - - - - - - - - - - - - - -
-
-
- - - ); -} - -Register.getLayout = function getLayout(page: ReactElement) { - return {page}; -};