From 3373401682c3078f0350f3da7b47f10284b58f6c Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 8 May 2026 01:48:35 +0000 Subject: [PATCH] Rrlabs 2.0 --- frontend/src/components/AsideMenuLayer.tsx | 115 +- frontend/src/components/FooterBar.tsx | 53 +- frontend/src/components/NavBar.tsx | 52 +- frontend/src/components/NavBarItem.tsx | 3 +- frontend/src/components/RrlabsBrand.tsx | 49 + .../src/components/marketing/LegalPage.tsx | 56 + .../marketing/PublicMarketingShell.tsx | 155 ++ frontend/src/data/rrlabsContent.ts | 369 ++++ frontend/src/layouts/Authenticated.tsx | 8 +- frontend/src/menuAside.ts | 6 + frontend/src/pages/blog/[slug].tsx | 119 ++ frontend/src/pages/blog/index.tsx | 98 + frontend/src/pages/index.tsx | 422 +++-- frontend/src/pages/pricing.tsx | 99 + frontend/src/pages/privacy-policy.tsx | 291 +-- frontend/src/pages/recovery-studio.tsx | 1640 +++++++++++++++++ frontend/src/pages/refund-policy.tsx | 13 + frontend/src/pages/search.tsx | 4 +- frontend/src/pages/terms-of-service.tsx | 13 + frontend/src/pages/terms-of-use.tsx | 205 +-- 20 files changed, 3020 insertions(+), 750 deletions(-) create mode 100644 frontend/src/components/RrlabsBrand.tsx create mode 100644 frontend/src/components/marketing/LegalPage.tsx create mode 100644 frontend/src/components/marketing/PublicMarketingShell.tsx create mode 100644 frontend/src/data/rrlabsContent.ts create mode 100644 frontend/src/pages/blog/[slug].tsx create mode 100644 frontend/src/pages/blog/index.tsx create mode 100644 frontend/src/pages/pricing.tsx create mode 100644 frontend/src/pages/recovery-studio.tsx create mode 100644 frontend/src/pages/refund-policy.tsx create mode 100644 frontend/src/pages/terms-of-service.tsx diff --git a/frontend/src/components/AsideMenuLayer.tsx b/frontend/src/components/AsideMenuLayer.tsx index edd7c67..6ad8900 100644 --- a/frontend/src/components/AsideMenuLayer.tsx +++ b/frontend/src/components/AsideMenuLayer.tsx @@ -1,88 +1,77 @@ -import React from 'react' -import { mdiLogout, mdiClose } from '@mdi/js' -import BaseIcon from './BaseIcon' -import AsideMenuList from './AsideMenuList' -import { MenuAsideItem } from '../interfaces' -import { useAppSelector } from '../stores/hooks' +import React from 'react'; +import { mdiClose } from '@mdi/js'; import Link from 'next/link'; - -import { useAppDispatch } from '../stores/hooks'; -import { createAsyncThunk } from '@reduxjs/toolkit'; import axios from 'axios'; - +import BaseIcon from './BaseIcon'; +import AsideMenuList from './AsideMenuList'; +import RrlabsBrand from './RrlabsBrand'; +import { MenuAsideItem } from '../interfaces'; +import { useAppSelector } from '../stores/hooks'; type Props = { - menu: MenuAsideItem[] - className?: string - onAsideLgCloseClick: () => void -} + menu: MenuAsideItem[]; + className?: string; + onAsideLgCloseClick: () => void; +}; + +type Organization = { + id: string; + name: string; +}; export default function AsideMenuLayer({ menu, className = '', ...props }: Props) { const corners = useAppSelector((state) => state.style.corners); - const asideStyle = useAppSelector((state) => state.style.asideStyle) - const asideBrandStyle = useAppSelector((state) => state.style.asideBrandStyle) - const asideScrollbarsStyle = useAppSelector((state) => state.style.asideScrollbarsStyle) - const darkMode = useAppSelector((state) => state.style.darkMode) + const asideStyle = useAppSelector((state) => state.style.asideStyle); + const asideScrollbarsStyle = useAppSelector((state) => state.style.asideScrollbarsStyle); + const darkMode = useAppSelector((state) => state.style.darkMode); + const { currentUser } = useAppSelector((state) => state.auth); + const [organizations, setOrganizations] = React.useState([]); const handleAsideLgCloseClick = (e: React.MouseEvent) => { - e.preventDefault() - props.onAsideLgCloseClick() - } - - const dispatch = useAppDispatch(); - const { currentUser } = useAppSelector((state) => state.auth); - const organizationsId = currentUser?.organizations?.id; - const [organizations, setOrganizations] = React.useState(null); - - const fetchOrganizations = createAsyncThunk('/org-for-auth', async () => { - try { - const response = await axios.get('/org-for-auth'); - setOrganizations(response.data); - return response.data; - } catch (error) { - console.error(error.response); - throw error; - } - }); + e.preventDefault(); + props.onAsideLgCloseClick(); + }; React.useEffect(() => { - dispatch(fetchOrganizations()); - }, [dispatch]); + const loadOrganizations = async () => { + try { + const response = await axios.get('org-for-auth'); + setOrganizations(Array.isArray(response.data) ? response.data : []); + } catch (error) { + console.error('Failed to load organizations for aside menu', error); + } + }; - let organizationName = organizations?.find(item => item.id === organizationsId)?.name; - if(organizationName?.length > 25){ - organizationName = organizationName?.substring(0, 25) + '...'; + loadOrganizations(); + }, []); + + const organizationsId = currentUser?.organizations?.id; + let organizationName = organizations.find((item) => item.id === organizationsId)?.name; + if (organizationName && organizationName.length > 25) { + organizationName = `${organizationName.substring(0, 25)}...`; } - return ( - ) + ); } diff --git a/frontend/src/components/FooterBar.tsx b/frontend/src/components/FooterBar.tsx index 0acc9c5..2a4f7eb 100644 --- a/frontend/src/components/FooterBar.tsx +++ b/frontend/src/components/FooterBar.tsx @@ -1,35 +1,40 @@ -import React, { ReactNode } from 'react' -import { containerMaxW } from '../config' -import Logo from './Logo' +import React, { ReactNode } from 'react'; +import Link from 'next/link'; +import { containerMaxW } from '../config'; +import RrlabsBrand from './RrlabsBrand'; type Props = { - children?: ReactNode -} + children?: ReactNode; +}; export default function FooterBar({ children }: Props) { - const year = new Date().getFullYear() + const year = new Date().getFullYear(); return ( -