From 3340615e1ffd0ed1037ec1d145854169df16b50f Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 9 Jun 2026 12:32:10 +0000 Subject: [PATCH] Restyle login page for coaching workspace --- frontend/src/pages/login.tsx | 474 ++++++++++++++++++----------------- 1 file changed, 241 insertions(+), 233 deletions(-) diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx index 85c9427..dc1465a 100644 --- a/frontend/src/pages/login.tsx +++ b/frontend/src/pages/login.tsx @@ -1,273 +1,281 @@ - - 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 Link from 'next/link'; 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 { mdiEye, mdiEyeOff } from '@mdi/js'; +import { toast, ToastContainer } from 'react-toastify'; import { useRouter } from 'next/router'; +import BaseIcon from '../components/BaseIcon'; +import LayoutGuest from '../layouts/Guest'; 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' + +const ui = { + page: 'bg-[#fffdf9] text-[#19192d]', + banner: + 'bg-gradient-to-r from-[#35b7a5] via-[#95b76e] to-[#c38a25] text-white', + navShell: + 'rounded-full bg-white shadow-[0_18px_60px_rgba(31,31,50,0.08)] ring-1 ring-[#19192d]/5', + ink: 'text-[#19192d]', + muted: 'text-[#72798a]', + accent: 'text-[#35b7a5]', + gold: 'text-[#b17a1e]', + border: 'border-[#19192d]/10', + surface: 'bg-white', + softSurface: 'bg-[#fbf8f1]', + darkPanel: 'bg-[#19192d] text-white', + button: + 'bg-gradient-to-r from-[#36b39f] to-[#b98624] text-white shadow-[0_18px_45px_rgba(54,179,159,0.24)] transition hover:brightness-105', + card: 'rounded-[1.75rem] border border-[#19192d]/10 bg-white shadow-[0_18px_50px_rgba(31,31,50,0.05)]', + overline: 'text-sm font-bold uppercase tracking-[0.28em] text-[#b17a1e]', + heading: 'font-serif font-semibold tracking-tight text-[#19192d]', +}; + +type LoginValues = { + email: string; + password: string; + remember: boolean; +}; + +function Nav() { + return ( +
+
+ + + C + + Coaching SaaS Workspace + + + + Join waitlist + +
+
+ ); +} 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('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', + const [showPassword, setShowPassword] = useState(false); + const { + currentUser, + isFetching, + errorMessage, + token, + notify: notifyState, + } = useAppSelector((state) => state.auth); + + const initialValues: LoginValues = { + email: 'admin@flatlogic.com', password: 'f76d928f', - remember: true }) + remember: true, + }; - const title = 'Coaching SaaS Workspace' - - // 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) + if (errorMessage) { + toast(errorMessage, { type: 'error' }); } + }, [errorMessage]); - }, [errorMessage]) - // Show notification if there is one useEffect(() => { - if (notifyState?.showNotification) { - notify('success', notifyState?.textNotification) - dispatch(resetAction()); - } - }, [notifyState?.showNotification]) + if (notifyState?.showNotification) { + toast(notifyState?.textNotification, { type: 'success' }); + dispatch(resetAction()); + } + }, [notifyState?.showNotification, notifyState?.textNotification, dispatch]); - 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 - -
-
) - } - }; + async function handleSubmit(values: LoginValues) { + const { remember, ...credentials } = values; + await dispatch(loginUser(credentials)); + } return ( -
- - {getPageTitle('Login')} - + <> + + {getPageTitle('Login')} + - -
- {contentType === 'image' && contentPosition !== 'background' ? imageBlock(illustrationImage) : null} - {contentType === 'video' && contentPosition !== 'background' ? videoBlock(illustrationVideo) : null} -
- - - -

{title}

- -
-
- -

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

-

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

-
-
- -
-
-
- - - handleSubmit(values)} - > -
- - - +
+
+

+ Still human +

+

+ AI is not a coach. Keep the real relationship at the center. +

+
-
- - - -
- -
-
+
+ +
+
+
+

Sign in

+

+ Open your workspace +

+

+ Use your workspace credentials to continue. +

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

+ Don't have an account yet?{' '} + + Create one + +

+
+
+ + +
+
+

© 2026 Coaching SaaS Workspace. Coaching beyond the session.

+
+ Privacy Policy + Terms of Use +
+
+
+ + + + ); }