mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-09 15:05:35 +00:00
feat: add about page
Finally!
This commit is contained in:
28
public/locales/en/about.json
Normal file
28
public/locales/en/about.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"hero": {
|
||||
"title": "Welcome to MyLinks",
|
||||
"cta": "Get started"
|
||||
},
|
||||
"category": {
|
||||
"title": "Create categories",
|
||||
"text": "Organize your bookmarks by categories to keep your links tidy and find them easily."
|
||||
},
|
||||
"link": {
|
||||
"title": "Manage Links",
|
||||
"text": "Add, edit, and manage your bookmarks with a simple and intuitive interface."
|
||||
},
|
||||
"search": {
|
||||
"title": "Search",
|
||||
"text": "Quickly find the bookmark you're looking for with the powerful search feature."
|
||||
},
|
||||
"extension": {
|
||||
"title": "Browser extension",
|
||||
"text": "Enhance your experience with the official MyLinks browser extension."
|
||||
},
|
||||
"contribute": {
|
||||
"title": "Contribute to MyLinks",
|
||||
"text": "Suggest improvements you would like to see on MyLinks."
|
||||
},
|
||||
"look-title": "Take a look",
|
||||
"website-screenshot-alt": "A screenshot of MyLinks"
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"slogan": "Manage your links in the best possible way",
|
||||
"confirm": "Confirm",
|
||||
"cancel": "Cancel",
|
||||
"back-home": "← Back to home page",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"title": "Authentication",
|
||||
"informative-text": "Authentication required to use MyLinks",
|
||||
"continue-with": "Continue with {{provider}}",
|
||||
"slogan": "Manage your links in the best possible way"
|
||||
"continue-with": "Continue with {{provider}}"
|
||||
}
|
||||
|
||||
28
public/locales/fr/about.json
Normal file
28
public/locales/fr/about.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"hero": {
|
||||
"title": "Bienvenue sur MyLinks",
|
||||
"cta": "Lancez-vous !"
|
||||
},
|
||||
"category": {
|
||||
"title": "Créer des catégories",
|
||||
"text": "Organisez vos favoris dans des catégories pour garder vos liens en ordre et les retrouver facilement."
|
||||
},
|
||||
"link": {
|
||||
"title": "Gérer les liens",
|
||||
"text": "Ajoutez, modifiez et gérez vos favoris à l'aide d'une interface simple et intuitive."
|
||||
},
|
||||
"search": {
|
||||
"title": "Rechercher",
|
||||
"text": "Trouvez rapidement vos liens favoris en utilisant la fonction de recherche."
|
||||
},
|
||||
"extension": {
|
||||
"title": "Extension de navigateur",
|
||||
"text": "Améliorez votre expérience avec l'extension de navigateur officielle MyLinks."
|
||||
},
|
||||
"contribute": {
|
||||
"title": "Contribuer à MyLinks",
|
||||
"text": "Proposez des améliorations que vous souhaiteriez voir sur MyLinks."
|
||||
},
|
||||
"look-title": "Jetez un coup d'oeil",
|
||||
"website-screenshot-alt": "Une capture d'écran de MyLinks"
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"slogan": "Gérez vos liens de la meilleure des façons",
|
||||
"confirm": "Confirmer",
|
||||
"cancel": "Annuler",
|
||||
"back-home": "← Revenir à l'accueil",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"title": "Authentification",
|
||||
"informative-text": "Authentification requise pour utiliser MyLinks",
|
||||
"continue-with": "Continuer avec {{provider}}",
|
||||
"slogan": "Gérez vos liens de la meilleure des façons"
|
||||
"continue-with": "Continuer avec {{provider}}"
|
||||
}
|
||||
|
||||
BIN
public/website-screenshot.png
Normal file
BIN
public/website-screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
@@ -22,10 +22,7 @@ export default function Navbar() {
|
||||
<LinkTag href={PATHS.HOME}>MyLinks</LinkTag>
|
||||
</li>
|
||||
<li>
|
||||
<LinkTag href={PATHS.PRIVACY}>{t('common:privacy')}</LinkTag>
|
||||
</li>
|
||||
<li>
|
||||
<LinkTag href={PATHS.TERMS}>{t('common:terms')}</LinkTag>
|
||||
<LinkTag href={PATHS.REPO_GITHUB}>GitHub</LinkTag>
|
||||
</li>
|
||||
{status === 'authenticated' ? (
|
||||
<>
|
||||
|
||||
8
src/components/Quotes/Quotes.tsx
Normal file
8
src/components/Quotes/Quotes.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import { ReactNode } from 'react';
|
||||
import styles from './quotes.module.scss';
|
||||
|
||||
const Quotes = ({ children }: { children: ReactNode }) => (
|
||||
<p className={styles['quotes']}>{children}</p>
|
||||
);
|
||||
|
||||
export default Quotes;
|
||||
25
src/components/Quotes/quotes.module.scss
Normal file
25
src/components/Quotes/quotes.module.scss
Normal file
@@ -0,0 +1,25 @@
|
||||
@import 'styles/colors.scss';
|
||||
|
||||
.quotes {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
white-space: pre-wrap;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
color: rgba($color: $black, $alpha: 0.75);
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: -0.65em;
|
||||
content: '“';
|
||||
font-family: sans-serif;
|
||||
font-size: 2.25em;
|
||||
}
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: -0.5em;
|
||||
content: '”';
|
||||
font-family: sans-serif;
|
||||
font-size: 2.25em;
|
||||
}
|
||||
}
|
||||
104
src/pages/about.tsx
Normal file
104
src/pages/about.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import clsx from 'clsx';
|
||||
import Footer from 'components/Footer/Footer';
|
||||
import Navbar from 'components/Navbar/Navbar';
|
||||
import PageTransition from 'components/PageTransition';
|
||||
import { getServerSideTranslation } from 'i18n';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { IconType } from 'react-icons';
|
||||
import { AiFillFolderOpen } from 'react-icons/ai';
|
||||
import { FaUser } from 'react-icons/fa';
|
||||
import { IoIosLink, IoIosSearch } from 'react-icons/io';
|
||||
import { IoExtensionPuzzleOutline } from 'react-icons/io5';
|
||||
import websiteScreenshot from '../../public/website-screenshot.png';
|
||||
|
||||
import Quotes from 'components/Quotes/Quotes';
|
||||
import styles from 'styles/about.module.scss';
|
||||
|
||||
export default function AboutPage() {
|
||||
const { t } = useTranslation('about');
|
||||
return (
|
||||
<PageTransition className={clsx('App', styles['about-page'])}>
|
||||
<Navbar />
|
||||
<HeroHeader />
|
||||
<div className={styles['page-content']}>
|
||||
<ul className={`reset ${styles['about-list']}`}>
|
||||
<AboutItem
|
||||
icon={AiFillFolderOpen}
|
||||
title={t('about:category.title')}
|
||||
text={t('about:category.text')}
|
||||
/>
|
||||
<AboutItem
|
||||
icon={IoIosLink}
|
||||
title={t('about:link.title')}
|
||||
text={t('about:link.text')}
|
||||
/>
|
||||
<AboutItem
|
||||
icon={IoIosSearch}
|
||||
title={t('about:search.title')}
|
||||
text={t('about:search.text')}
|
||||
/>
|
||||
<AboutItem
|
||||
icon={IoExtensionPuzzleOutline}
|
||||
title={t('about:extension.title')}
|
||||
text={t('about:extension.text')}
|
||||
/>
|
||||
<AboutItem
|
||||
icon={FaUser}
|
||||
title={t('about:contribute.title')}
|
||||
text={t('about:contribute.text')}
|
||||
/>
|
||||
</ul>
|
||||
<h2>{t('about:look-title')}</h2>
|
||||
<div className={styles['screenshot-wrapper']}>
|
||||
<Image
|
||||
src={websiteScreenshot}
|
||||
alt={t('about:website-screenshot-alt')}
|
||||
title={t('about:website-screenshot-alt')}
|
||||
fill
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</PageTransition>
|
||||
);
|
||||
}
|
||||
|
||||
const AboutItem = ({
|
||||
title,
|
||||
text,
|
||||
icon: Icon,
|
||||
}: {
|
||||
title: string;
|
||||
text: string;
|
||||
icon: IconType;
|
||||
}) => (
|
||||
<li className={styles['about-item']}>
|
||||
<Icon size={60} />
|
||||
<div>{title}</div>
|
||||
<p>{text}</p>
|
||||
</li>
|
||||
);
|
||||
|
||||
function HeroHeader() {
|
||||
const { t } = useTranslation('about');
|
||||
return (
|
||||
<header className={styles['hero']}>
|
||||
<h1>{t('about:hero.title')}</h1>
|
||||
<Quotes>{t('common:slogan')}</Quotes>
|
||||
<Link
|
||||
href='/login'
|
||||
className='reset'
|
||||
>
|
||||
{t('about:hero.cta')}
|
||||
</Link>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps = async ({ locale }) => ({
|
||||
props: {
|
||||
...(await getServerSideTranslation(locale, ['about'])),
|
||||
},
|
||||
});
|
||||
@@ -3,6 +3,7 @@ import Footer from 'components/Footer/Footer';
|
||||
import LangSelector from 'components/LangSelector';
|
||||
import MessageManager from 'components/MessageManager/MessageManager';
|
||||
import PageTransition from 'components/PageTransition';
|
||||
import Quotes from 'components/Quotes/Quotes';
|
||||
import PATHS from 'constants/paths';
|
||||
import getUser from 'lib/user/getUser';
|
||||
import { Provider } from 'next-auth/providers';
|
||||
@@ -35,7 +36,7 @@ export default function SignIn({ providers }: Readonly<SignInProps>) {
|
||||
height={100}
|
||||
alt="MyLinks's logo"
|
||||
/>
|
||||
<p className={styles['slogan']}>{t('login:slogan')}</p>
|
||||
<Quotes>{t('common:slogan')}</Quotes>
|
||||
<div className={styles['form-wrapper']}>
|
||||
<h1>{t('login:title')}</h1>
|
||||
<MessageManager info={t('login:informative-text')} />
|
||||
|
||||
97
src/styles/about.module.scss
Normal file
97
src/styles/about.module.scss
Normal file
@@ -0,0 +1,97 @@
|
||||
@import 'colors.scss';
|
||||
|
||||
.about-page {
|
||||
height: unset;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
header.hero {
|
||||
height: 275px;
|
||||
min-height: 275px;
|
||||
width: 100%;
|
||||
background-color: $darkest-blue;
|
||||
margin-top: 0.5em;
|
||||
border-radius: 3px;
|
||||
padding: 1em;
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
& h1 {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
& p {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
& a {
|
||||
font-size: 16px;
|
||||
width: fit-content;
|
||||
background-color: $blue;
|
||||
border-radius: 5em;
|
||||
padding: 0.5em 1.5em;
|
||||
}
|
||||
|
||||
& * {
|
||||
color: $white;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.about-list {
|
||||
margin: 4em 0;
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.about-item {
|
||||
width: 350px;
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
& svg {
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
& div {
|
||||
font-size: 1.25em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
& p {
|
||||
color: $dark-grey;
|
||||
}
|
||||
}
|
||||
|
||||
.screenshot-wrapper {
|
||||
position: relative;
|
||||
height: 360px;
|
||||
width: 640px;
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
& img {
|
||||
height: auto !important;
|
||||
width: 100%;
|
||||
box-shadow: 0 0 1em 1px $lightest-grey;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,14 @@ $lightest-blue: #d3e8fa;
|
||||
$light-blue: #82c5fede;
|
||||
$blue: #3f88c5;
|
||||
$dark-blue: #005aa5;
|
||||
$darkest-blue: #1f2937;
|
||||
|
||||
$white: #fff;
|
||||
|
||||
$lightest-grey: #dadce0;
|
||||
$light-grey: #f0eef6;
|
||||
$grey: #aaa;
|
||||
$dark-grey: #4b5563;
|
||||
|
||||
$black: #333;
|
||||
$black-blur: rgba(0, 0, 0, 0.3);
|
||||
|
||||
@@ -12,13 +12,11 @@
|
||||
html,
|
||||
body {
|
||||
height: 100dvh;
|
||||
width: 100dvw;
|
||||
color: $black;
|
||||
background-color: $light-grey;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#__next {
|
||||
|
||||
@@ -21,30 +21,6 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.slogan {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
white-space: pre-wrap;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
color: rgba($color: $black, $alpha: 0.75);
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: -0.65em;
|
||||
content: '“';
|
||||
font-family: sans-serif;
|
||||
font-size: 2.25em;
|
||||
}
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: -0.5em;
|
||||
content: '”';
|
||||
font-family: sans-serif;
|
||||
font-size: 2.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
width: 100%;
|
||||
background-color: $white;
|
||||
|
||||
Reference in New Issue
Block a user