diff --git a/assets/pasted-20260213-042016-0d300935.jpg b/assets/pasted-20260213-042016-0d300935.jpg new file mode 100644 index 0000000..8d86a24 Binary files /dev/null and b/assets/pasted-20260213-042016-0d300935.jpg differ diff --git a/frontend/public/payment-qr.jpg b/frontend/public/payment-qr.jpg new file mode 100644 index 0000000..a14b617 Binary files /dev/null and b/frontend/public/payment-qr.jpg differ diff --git a/frontend/public/pix-qr.jpg b/frontend/public/pix-qr.jpg new file mode 100644 index 0000000..8d86a24 Binary files /dev/null and b/frontend/public/pix-qr.jpg differ diff --git a/frontend/src/components/NavBarItem.tsx b/frontend/src/components/NavBarItem.tsx index a191d43..9d9173c 100644 --- a/frontend/src/components/NavBarItem.tsx +++ b/frontend/src/components/NavBarItem.tsx @@ -7,7 +7,7 @@ import UserAvatarCurrentUser from './UserAvatarCurrentUser' import NavBarMenuList from './NavBarMenuList' import { useAppDispatch, useAppSelector } from '../stores/hooks' import { MenuNavBarItem } from '../interfaces' -import { setAsideLgActive } from '../stores/styleSlice' +import { logoutUser } from '../stores/authSlice' type Props = { item: MenuNavBarItem @@ -45,7 +45,8 @@ export default function NavBarItem({ item }: Props) { } if (item.isLogout) { - // + dispatch(logoutUser()) + router.push('/admin-login') } } @@ -106,4 +107,4 @@ export default function NavBarItem({ item }: Props) { } return
{NavBarItemComponentContents}
-} \ No newline at end of file +} diff --git a/frontend/src/components/PasswordSetOrReset.tsx b/frontend/src/components/PasswordSetOrReset.tsx index 07749ba..9a341f1 100644 --- a/frontend/src/components/PasswordSetOrReset.tsx +++ b/frontend/src/components/PasswordSetOrReset.tsx @@ -40,7 +40,7 @@ export default function PasswordSetOrReset() { type: isInvitation && 'invitation', }), ); - await router.push('/login'); + await router.push('/admin-login'); } setLoading(false); @@ -110,4 +110,4 @@ export default function PasswordSetOrReset() { ); -} +} \ No newline at end of file diff --git a/frontend/src/layouts/Authenticated.tsx b/frontend/src/layouts/Authenticated.tsx index 26c3572..15a9f3c 100644 --- a/frontend/src/layouts/Authenticated.tsx +++ b/frontend/src/layouts/Authenticated.tsx @@ -52,7 +52,7 @@ export default function LayoutAuthenticated({ dispatch(findMe()); if (!isTokenValid()) { dispatch(logoutUser()); - router.push('/login'); + router.push('/admin-login'); } }, [token, localToken]); @@ -125,4 +125,4 @@ export default function LayoutAuthenticated({ ) -} \ No newline at end of file +} 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/index.tsx b/frontend/src/pages/index.tsx index b665d19..27dd7e6 100644 --- a/frontend/src/pages/index.tsx +++ b/frontend/src/pages/index.tsx @@ -258,9 +258,7 @@ export default function IndexPage() { NEXUS GAMES
GALLERY -

- Unlock premium high-fidelity games instantly. All games are fully functional and ready to play in your browser. -

+

PREMIUM AI-POWERED GAMING

@@ -423,22 +421,16 @@ export default function IndexPage() {
-

Fast Payment

-

Scan with your mobile bank

+

Official Payment

+

Scan QR Code for Instant Access

-
-
-
- PIX +
+
+
+ Payment QR
- Pix Network -
-
-
- PayPal -
- PayPal Direct + Official Payment Network
diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx deleted file mode 100644 index d678841..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('video'); - const [contentPosition, setContentPosition] = useState('right'); - 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: '8ab6346a', - remember: true }) - - const title = 'AI Game Studio Marketplace' - - // 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) => ( - - ) - - const videoBlock = (video) => { - if (video?.video_files?.length > 0) { - return ( -
- - -
) - } - }; - - 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{' / '} - 8ab6346a{' / '} - to login as Admin

-

Use setLogin(e.target)}>client@hello.com{' / '} - c3af9d1c13ec{' / '} - 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}; -}; diff --git a/frontend/src/pages/verify-email.tsx b/frontend/src/pages/verify-email.tsx index 6cf0340..f13a20e 100644 --- a/frontend/src/pages/verify-email.tsx +++ b/frontend/src/pages/verify-email.tsx @@ -1,62 +1,83 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import type { ReactElement } from 'react'; -import { ToastContainer, toast } from 'react-toastify'; import Head from 'next/head'; -import CardBox from '../components/CardBox'; +import { useRouter } from 'next/router'; +import axios from 'axios'; +import { mdiCheckCircleOutline, mdiAlertCircleOutline } from '@mdi/js'; +import BaseIcon from '../components/BaseIcon'; import SectionFullScreen from '../components/SectionFullScreen'; import LayoutGuest from '../layouts/Guest'; -import { useRouter } from 'next/router'; import { getPageTitle } from '../config'; -import axios from 'axios'; -export default function Verify() { - const [loading, setLoading] = React.useState(false); - const router = useRouter(); - const { token } = router.query; - const notify = (type, msg) => toast(msg, { type }); +export default function VerifyEmail() { + const router = useRouter(); + const { token } = router.query; + const [status, setStatus] = useState<'loading' | 'success' | 'error'>('loading'); - React.useEffect(() => { - if (!token) { - router.push('/login'); - return; - } - const handleSubmit = async () => { + useEffect(() => { + if (token) { + axios + .put('/auth/verify-email', { token }) + .then(() => { + setStatus('success'); + setTimeout(() => { + router.push('/admin-login'); + }, 3000); + }) + .catch(() => { + setStatus('error'); + }); + } + }, [token, router]); - setLoading(true); - await axios.put('/auth/verify-email', { - token, - }).then(verified => { - if (verified) { - setLoading(false); - notify('success', 'Your email was verified'); - } - }).catch(error => { - setLoading(false); - console.log('error: ', error); - notify('error', error.response); - }).finally(async () => { - await router.push('/login'); - }); - }; - handleSubmit().then(); - }, [token]); + const renderContent = () => { + switch (status) { + case 'loading': + return ( +
+

Verifying your email...

+
+
+ ); + case 'success': + return ( +
+ +

Email Verified!

+

Your email has been successfully verified. Redirecting you to login...

+
+ ); + case 'error': + return ( +
+ +

Verification Failed

+

The verification link is invalid or has expired.

+ +
+ ); + } + }; - return ( - <> - - {getPageTitle('Verify Email')} - - - -

{loading ? 'Loading...' : ''}

-
-
- - - - ); + return ( + <> + + {getPageTitle('Verify Email')} + + +
+ {renderContent()} +
+
+ + ); } -Verify.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; +VerifyEmail.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; \ No newline at end of file