From 5c4ee3a1cd395cf124c03007f7575bcd81777e1b Mon Sep 17 00:00:00 2001 From: Sonny Date: Thu, 31 Oct 2024 02:25:59 +0100 Subject: [PATCH] refactor(mantine): migrate home page --- .../common/mantine_theme_switcher.tsx | 16 ++ inertia/components/home/about/about_item.tsx | 43 ------ inertia/components/home/about/about_list.tsx | 13 -- inertia/components/home/hero_header.tsx | 54 ------- inertia/components/home/website_preview.tsx | 34 ----- .../layouts/mantine/_mantine_base_layout.tsx | 1 + .../mantine/mantine_content_layout.tsx | 22 +-- inertia/components/navbar/mantine_navbar.tsx | 23 +-- inertia/i18n/locales/en/about.json | 1 + inertia/i18n/locales/fr/about.json | 1 + inertia/pages/home.module.css | 26 ++++ inertia/pages/home.tsx | 137 +++++++++++------- inertia/styles/index.css | 6 + 13 files changed, 160 insertions(+), 217 deletions(-) create mode 100644 inertia/components/common/mantine_theme_switcher.tsx delete mode 100644 inertia/components/home/about/about_item.tsx delete mode 100644 inertia/components/home/about/about_list.tsx delete mode 100644 inertia/components/home/hero_header.tsx delete mode 100644 inertia/components/home/website_preview.tsx create mode 100644 inertia/pages/home.module.css create mode 100644 inertia/styles/index.css diff --git a/inertia/components/common/mantine_theme_switcher.tsx b/inertia/components/common/mantine_theme_switcher.tsx new file mode 100644 index 0000000..84ada9d --- /dev/null +++ b/inertia/components/common/mantine_theme_switcher.tsx @@ -0,0 +1,16 @@ +import { useMantineColorScheme, ActionIcon } from '@mantine/core'; +import { TbSun, TbMoonStars } from 'react-icons/tb'; + +export function MantineThemeSwitcher() { + const { colorScheme, toggleColorScheme } = useMantineColorScheme(); + return ( + toggleColorScheme()} + size="lg" + > + {colorScheme === 'dark' ? : } + + ); +} diff --git a/inertia/components/home/about/about_item.tsx b/inertia/components/home/about/about_item.tsx deleted file mode 100644 index af9a8d1..0000000 --- a/inertia/components/home/about/about_item.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import styled from '@emotion/styled'; -import { IconType } from 'react-icons/lib'; - -const AboutItemStyle = styled.li(({ theme }) => ({ - width: '350px', - display: 'flex', - gap: '1em', - alignItems: 'center', - justifyContent: 'center', - flexDirection: 'column', - - '& svg': { - color: theme.colors.blue, - }, - - '& div': { - fontSize: '1.25rem', - fontWeight: '500', - }, - - '& p': { - height: '65px', - color: theme.colors.grey, - }, -})); - -const AboutItem = ({ - title, - text, - icon: Icon, -}: { - title: string; - text: string; - icon: IconType; -}) => ( - - -
{title}
-

{text}

-
-); - -export default AboutItem; diff --git a/inertia/components/home/about/about_list.tsx b/inertia/components/home/about/about_list.tsx deleted file mode 100644 index 46681a6..0000000 --- a/inertia/components/home/about/about_list.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import styled from '@emotion/styled'; -import UnstyledList from '~/components/common/unstyled/unstyled_list'; - -const AboutList = styled(UnstyledList)({ - margin: '4em 0 !important', - display: 'flex', - gap: '2em', - alignItems: 'center', - justifyContent: 'center', - flexWrap: 'wrap', -}); - -export default AboutList; diff --git a/inertia/components/home/hero_header.tsx b/inertia/components/home/hero_header.tsx deleted file mode 100644 index 1334faf..0000000 --- a/inertia/components/home/hero_header.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import styled from '@emotion/styled'; -import { Link } from '@inertiajs/react'; -import { route } from '@izzyjs/route/client'; -import { useTranslation } from 'react-i18next'; -import Quotes from '~/components/quotes'; - -const HeroStyle = styled.header(({ theme }) => ({ - height: '250px', - minHeight: '250px', - width: '100%', - backgroundColor: theme.colors.secondary, - marginTop: '0.5em', - borderRadius: theme.border.radius, - padding: '1em', - display: 'flex', - gap: '1em', - alignItems: 'center', - justifyContent: 'center', - flexDirection: 'column', - - '& *': { - textAlign: 'center', - }, -})); - -const HeroTitle = styled.h1({ - fontSize: '32px', -}); - -const HeroQuote = styled(Quotes)({ - fontSize: '20px', -}); - -const LinkButton = styled(Link)(({ theme }) => ({ - fontSize: '1rem', - width: 'fit-content', - color: theme.colors.white, - backgroundColor: theme.colors.primary, - borderRadius: '5rem', - padding: '0.5em 1.5em', -})); - -export default function HeroHeader() { - const { t } = useTranslation(); - return ( - - {t('about:hero.title')} - {t('common:slogan')} - - {t('about:hero.cta')} - - - ); -} diff --git a/inertia/components/home/website_preview.tsx b/inertia/components/home/website_preview.tsx deleted file mode 100644 index 833cb26..0000000 --- a/inertia/components/home/website_preview.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import styled from '@emotion/styled'; -import { useTranslation } from 'react-i18next'; - -const ScreenshotWrapper = styled.div({ - position: 'relative', - height: '360px', - width: '640px', - maxWidth: '100%', - margin: '0 auto', -}); - -const Screenshot = styled.img(({ theme }) => ({ - height: 'auto !important', - width: '100%', - boxShadow: theme.colors.boxShadow, - borderRadius: theme.border.radius, - overflow: 'hidden', -})); - -export default function WebsitePreview() { - const { t } = useTranslation('about'); - return ( - <> -

{t('look-title')}

- - - - - ); -} diff --git a/inertia/components/layouts/mantine/_mantine_base_layout.tsx b/inertia/components/layouts/mantine/_mantine_base_layout.tsx index d64b10f..4f7ba2c 100644 --- a/inertia/components/layouts/mantine/_mantine_base_layout.tsx +++ b/inertia/components/layouts/mantine/_mantine_base_layout.tsx @@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next'; import '@mantine/core/styles.css'; import '@mantine/spotlight/styles.css'; +import '../../../styles/index.css'; const theme = createTheme({}); diff --git a/inertia/components/layouts/mantine/mantine_content_layout.tsx b/inertia/components/layouts/mantine/mantine_content_layout.tsx index 036ad5b..8439def 100644 --- a/inertia/components/layouts/mantine/mantine_content_layout.tsx +++ b/inertia/components/layouts/mantine/mantine_content_layout.tsx @@ -6,19 +6,23 @@ import MantineNavbar from '~/components/navbar/mantine_navbar'; function MantineContentLayout({ children }: PropsWithChildren) { return ( -
- - -
{children}
- -
-
+ +
+ {children} +
+ + ); } diff --git a/inertia/components/navbar/mantine_navbar.tsx b/inertia/components/navbar/mantine_navbar.tsx index ba39251..751b104 100644 --- a/inertia/components/navbar/mantine_navbar.tsx +++ b/inertia/components/navbar/mantine_navbar.tsx @@ -15,6 +15,7 @@ import { import { useDisclosure } from '@mantine/hooks'; import { useTranslation } from 'react-i18next'; import ExternalLink from '~/components/common/external_link'; +import { MantineThemeSwitcher } from '~/components/common/mantine_theme_switcher'; import classes from './mobile_navbar.module.css'; export default function MantineNavbar() { @@ -29,7 +30,7 @@ export default function MantineNavbar() { MyLinks's logo - + {t('home')} @@ -40,17 +41,21 @@ export default function MantineNavbar() { - - + - - diff --git a/inertia/i18n/locales/en/about.json b/inertia/i18n/locales/en/about.json index abac1d9..313c174 100644 --- a/inertia/i18n/locales/en/about.json +++ b/inertia/i18n/locales/en/about.json @@ -3,6 +3,7 @@ "title": "Welcome to MyLinks", "cta": "Get started" }, + "description": "An open-source, self-hosted bookmark manager that lets you manage your favorite links in an intuitive interface", "collection": { "title": "Create collections", "text": "Organize your bookmarks by collections to keep your links tidy and find them easily." diff --git a/inertia/i18n/locales/fr/about.json b/inertia/i18n/locales/fr/about.json index 18040b4..3aa8f73 100644 --- a/inertia/i18n/locales/fr/about.json +++ b/inertia/i18n/locales/fr/about.json @@ -3,6 +3,7 @@ "title": "Bienvenue sur MyLinks", "cta": "Lancez-vous !" }, + "description": "Un gestionnaire de favoris open-source et auto-hébergé qui vous permet de gérer vos liens favoris dans une interface intuitive", "collection": { "title": "Créer des collections", "text": "Organisez vos favoris dans des collections pour garder vos liens en ordre et les retrouver facilement." diff --git a/inertia/pages/home.module.css b/inertia/pages/home.module.css new file mode 100644 index 0000000..bde5e18 --- /dev/null +++ b/inertia/pages/home.module.css @@ -0,0 +1,26 @@ +.wrapper { + padding-top: calc(var(--mantine-spacing-xl) * 2); + padding-bottom: calc(var(--mantine-spacing-xl) * 2); +} + +.title { + font-family: + Greycliff CF, + var(--mantine-font-family); + font-weight: 900; + margin-bottom: var(--mantine-spacing-md); + text-align: center; + + @media (max-width: $mantine-breakpoint-sm) { + font-size: rem(28px); + text-align: left; + } +} + +.description { + text-align: center; + + @media (max-width: $mantine-breakpoint-sm) { + text-align: left; + } +} diff --git a/inertia/pages/home.tsx b/inertia/pages/home.tsx index 754a653..9dc79aa 100644 --- a/inertia/pages/home.tsx +++ b/inertia/pages/home.tsx @@ -1,68 +1,95 @@ -import styled from '@emotion/styled'; import { ReactNode } from 'react'; +import { MantineContentLayout } from '~/components/layouts/mantine/mantine_content_layout'; + +import { + Container, + SimpleGrid, + Text, + ThemeIcon, + Title, + rem, +} from '@mantine/core'; import { useTranslation } from 'react-i18next'; import { AiFillFolderOpen } from 'react-icons/ai'; import { FaUser } from 'react-icons/fa'; import { IoIosLink, IoIosSearch, IoIosShareAlt } from 'react-icons/io'; import { IoExtensionPuzzleOutline } from 'react-icons/io5'; -import AboutItem from '~/components/home/about/about_item'; -import AboutList from '~/components/home/about/about_list'; -import HeroHeader from '~/components/home/hero_header'; -import WebsitePreview from '~/components/home/website_preview'; -import ContentLayout from '~/components/layouts/content_layout'; +import classes from './home.module.css'; -const PageContent = styled.div({ - marginBottom: '4em', - textAlign: 'center', - display: 'flex', - gap: '2em', - flex: 1, - flexDirection: 'column', -}); +const features = [ + 'collection', + 'link', + 'search', + 'extension', + 'share', + 'contribute', +] as const; +type FeatureName = (typeof features)[number]; -function HomePage() { - const { t } = useTranslation(); +interface FeatureProps { + name: FeatureName; +} + +function getIcon(name: FeatureName) { + switch (name) { + case 'collection': + return AiFillFolderOpen; + case 'link': + return IoIosLink; + case 'search': + return IoIosSearch; + case 'extension': + return IoExtensionPuzzleOutline; + case 'share': + return IoIosShareAlt; + case 'contribute': + return FaUser; + } +} + +export function Feature({ name: featureName }: FeatureProps) { + const { t } = useTranslation('about'); + const Icon = getIcon(featureName); return ( - <> - - - - - - - - - - - - - +
+ + + + + {t(`${featureName}.title`)} + + + {t(`${featureName}.text`)} + +
); } -HomePage.layout = (page: ReactNode) => ; +function HomePage() { + const { t } = useTranslation('about'); + return ( + + {t('hero.title')} + + + + {t('description')} + + + + + {features.map((feature, index) => ( + + ))} + + + ); +} + +HomePage.layout = (page: ReactNode) => ; export default HomePage; diff --git a/inertia/styles/index.css b/inertia/styles/index.css new file mode 100644 index 0000000..091ecac --- /dev/null +++ b/inertia/styles/index.css @@ -0,0 +1,6 @@ +html, +body { + height: 100svh; + width: 100%; + background-color: light-dark(var(--mantine-color-white), rgb(34, 40, 49)); +}