feat: bring back legal pages

This commit is contained in:
Sonny
2024-05-20 01:07:11 +02:00
committed by Sonny
parent e6803c174c
commit 3ff7619e94
16 changed files with 190 additions and 46 deletions

View File

@@ -3,10 +3,6 @@ import { updateUserThemeValidator } from '#validators/user';
import type { HttpContext } from '@adonisjs/core/http';
export default class AppsController {
index({ inertia }: HttpContext) {
return inertia.render('home');
}
async updateUserTheme({ request, session, response }: HttpContext) {
const { preferDarkTheme } = await request.validateUsing(
updateUserThemeValidator

View File

@@ -1,6 +1,6 @@
import styled from '@emotion/styled';
const DropdownLabel = styled.p(({ theme }) => ({
const DropdownLabel = styled.div(({ theme }) => ({
height: 'auto',
width: 'auto',
color: theme.colors.font,

View File

@@ -8,7 +8,7 @@ const HeroStyle = styled.header(({ theme }) => ({
height: '250px',
minHeight: '250px',
width: '100%',
backgroundColor: theme.colors.darkestBlue,
backgroundColor: theme.colors.secondary,
marginTop: '0.5em',
borderRadius: theme.border.radius,
padding: '1em',
@@ -19,7 +19,6 @@ const HeroStyle = styled.header(({ theme }) => ({
flexDirection: 'column',
'& *': {
color: `${theme.colors.white} !important`,
textAlign: 'center',
},
}));
@@ -35,6 +34,7 @@ const HeroQuote = styled(Quotes)({
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',

View File

@@ -0,0 +1,36 @@
import styled from '@emotion/styled';
import { ReactNode } from 'react';
import ContentLayout from '~/components/layouts/content_layout';
import LegalFooter from '~/components/legal/legal_footer';
const LegalContentStyle = styled(ContentLayout)({
main: {
'h1, p': {
marginTop: '0.5em',
},
h2: {
marginTop: '1.5em',
},
h3: {
marginTop: '1em',
},
ul: {
marginLeft: '2em',
},
},
});
const LegalContentLayout = ({
children,
className,
}: {
children: ReactNode;
className?: string;
}) => (
<LegalContentStyle className={className}>
{children}
<LegalFooter />
</LegalContentStyle>
);
export default LegalContentLayout;

View File

@@ -0,0 +1,20 @@
import { useTranslation } from 'react-i18next';
import ExternalLink from '~/components/common/external_link';
export default function LegalFooter() {
const { t } = useTranslation('legal');
return (
<>
<h2>{t('contact.title')}</h2>
<p>
{t('contact.description')}{' '}
<ExternalLink href="mailto:sonnyasdev@gmail.com" target="_blank">
sonnyasdev[at]gmail[dot]com
</ExternalLink>
</p>
<p>{t('footer.changes')}</p>
<p css={{ marginBottom: '2em' }}>{t('footer.thanks')}</p>
</>
);
}

View File

@@ -9,8 +9,10 @@ import frResourceAdmin from './locales/fr/admin.json';
import frResourceCommon from './locales/fr/common.json';
import frResourceHome from './locales/fr/home.json';
import frResourceLogin from './locales/fr/login.json';
import frResourcePrivacy from './locales/fr/privacy.json';
import frResourceTerms from './locales/fr/terms.json';
import frResourceLegal from './locales/fr/legal.json';
import { LS_LANG_KEY } from '~/constants';
import enResourceAbout from './locales/en/about.json';
@@ -18,8 +20,10 @@ import enResourceAdmin from './locales/en/admin.json';
import enResourceCommon from './locales/en/common.json';
import enResourceHome from './locales/en/home.json';
import enResourceLogin from './locales/en/login.json';
import enResourcePrivacy from './locales/en/privacy.json';
import enResourceTerms from './locales/en/terms.json';
import enResourceLegal from './locales/en/legal.json';
type I18nFR =
| RemoveSuffix<Leaves<typeof frResourceAbout>>
@@ -28,7 +32,8 @@ type I18nFR =
| RemoveSuffix<Leaves<typeof frResourceHome>>
| RemoveSuffix<Leaves<typeof frResourceLogin>>
| RemoveSuffix<Leaves<typeof frResourcePrivacy>>
| RemoveSuffix<Leaves<typeof frResourceTerms>>;
| RemoveSuffix<Leaves<typeof frResourceTerms>>
| RemoveSuffix<Leaves<typeof frResourceLegal>>;
export type I18nKey = I18nFR;
export const resources = {
@@ -40,6 +45,7 @@ export const resources = {
login: enResourceLogin,
privacy: enResourcePrivacy,
terms: enResourceTerms,
legal: enResourceLegal,
},
fr: {
about: frResourceAbout,
@@ -49,6 +55,7 @@ export const resources = {
login: frResourceLogin,
privacy: frResourcePrivacy,
terms: frResourceTerms,
legal: frResourceLegal,
},
} as const;

View File

@@ -0,0 +1,10 @@
{
"contact": {
"title": "Contact",
"description": "For any questions or concerns regarding these Terms and Conditions of Use, please contact us at the following address:"
},
"footer": {
"changes": "We reserve the right to update these Terms and Conditions of Use. We encourage you to regularly check this page to stay informed of any changes.",
"thanks": "Thank you for using MyLinks!"
}
}

View File

@@ -39,13 +39,5 @@
"gdpr": {
"title": "5. GDPR Compliance",
"description": "MyLinks complies with the General Data Protection Regulation (GDPR) of the European Union."
},
"contact": {
"title": "6. Contact",
"description": "If you have any questions or concerns about our privacy policy, feel free to contact us at the following address:"
},
"footer": {
"changes": "We reserve the right to update this privacy policy. We encourage you to regularly check this page to stay informed of any changes.",
"thanks": "Thank you for using MyLinks!"
}
}

View File

@@ -50,13 +50,5 @@
"cancel": {
"title": "6. Termination",
"description": "MyLinks reserves the right to terminate or suspend your access to the service, with or without notice, in case of violation of these Terms and Conditions of Use."
},
"contact": {
"title": "7. Contact",
"description": "For any questions or concerns regarding these Terms and Conditions of Use, please contact us at the following address:"
},
"footer": {
"changes": "We reserve the right to update these Terms and Conditions of Use. We encourage you to regularly check this page to stay informed of any changes.",
"thanks": "Thank you for using MyLinks!"
}
}
}

View File

@@ -0,0 +1,10 @@
{
"contact": {
"title": "Contact",
"description": "Pour toute question ou préoccupation concernant ces Conditions Générales d'Utilisation, veuillez nous contacter à l'adresse suivante :"
},
"footer": {
"changes": "Nous nous réservons le droit de mettre à jour ces Conditions Générales d'Utilisation. Nous vous encourageons à consulter régulièrement cette page pour rester informé des changements éventuels.",
"thanks": "Merci d'utiliser MyLinks !"
}
}

View File

@@ -39,13 +39,5 @@
"gdpr": {
"title": "5. Conformité au RGPD",
"description": "MyLinks est conforme au Règlement Général sur la Protection des Données (RGPD) de l'Union européenne."
},
"contact": {
"title": "6. Contact",
"description": "Si vous avez des questions ou des préoccupations concernant notre politique de confidentialité, n'hésitez pas à nous contacter à l'adresse suivante :"
},
"footer": {
"changes": "Nous nous réservons le droit de mettre à jour cette politique de confidentialité. Nous vous encourageons à consulter régulièrement cette page pour rester informé des changements éventuels.",
"thanks": "Merci d'utiliser MyLinks !"
}
}

View File

@@ -50,13 +50,5 @@
"cancel": {
"title": "6. Résiliation",
"description": "MyLinks se réserve le droit de résilier ou de suspendre votre accès au service, avec ou sans préavis, en cas de violation de ces Conditions Générales d'Utilisation."
},
"contact": {
"title": "7. Contact",
"description": "Pour toute question ou préoccupation concernant ces Conditions Générales d'Utilisation, veuillez nous contacter à l'adresse suivante :"
},
"footer": {
"changes": "Nous nous réservons le droit de mettre à jour ces Conditions Générales d'Utilisation. Nous vous encourageons à consulter régulièrement cette page pour rester informé des changements éventuels.",
"thanks": "Merci d'utiliser MyLinks !"
}
}
}

View File

@@ -19,7 +19,7 @@ const PageContent = styled.div({
flexDirection: 'column',
});
export default function Home() {
export default function HomePage() {
const { t } = useTranslation();
return (
<ContentLayout>

44
inertia/pages/privacy.tsx Normal file
View File

@@ -0,0 +1,44 @@
import { useTranslation } from 'react-i18next';
import LegalContentLayout from '~/components/layouts/legal_content_layout';
export default function TermsPage() {
const { t } = useTranslation('privacy');
return (
<LegalContentLayout>
<h1>{t('title')}</h1>
<p>{t('edited_at', { date: '19/11/2023' })}</p>
<p>{t('welcome')}</p>
<h2>{t('collect.title')}</h2>
<h3>{t('collect.cookie.title')}</h3>
<p>{t('collect.cookie.description')}</p>
<h3>{t('collect.user.title')}</h3>
<p>{t('collect.user.description')}</p>
<ul>
{(
t('collect.user.fields', {
returnObjects: true,
}) as Array<string>
).map((field) => (
<li key={field}>{field}</li>
))}
</ul>
<h2>{t('data_use.title')}</h2>
<p>{t('data_use.description')}</p>
<h2>{t('data_storage.title')}</h2>
<p>{t('data_storage.description')}</p>
<h3>{t('data_storage.data_retention.title')}</h3>
<p>{t('data_storage.data_retention.description')}</p>
<h2>{t('user_rights.title')}</h2>
<p>{t('user_rights.description')}</p>
<h2>{t('gdpr.title')}</h2>
<p>{t('gdpr.description')}</p>
</LegalContentLayout>
);
}

53
inertia/pages/terms.tsx Normal file
View File

@@ -0,0 +1,53 @@
import { Link } from '@inertiajs/react';
import { route } from '@izzyjs/route/client';
import { Trans, useTranslation } from 'react-i18next';
import LegalContentLayout from '~/components/layouts/legal_content_layout';
export default function TermsPage() {
const { t } = useTranslation('terms');
return (
<LegalContentLayout>
<h1>{t('title')}</h1>
<p>{t('edited_at', { date: '19/11/2023' })}</p>
<p>{t('welcome')}</p>
<h2>{t('accept.title')}</h2>
<p>{t('accept.description')}</p>
<h2>{t('use.title')}</h2>
<h3>{t('use.account.title')}</h3>
<p>{t('use.account.description')}</p>
<h3>{t('use.allowed.title')}</h3>
<p>{t('use.allowed.description')}</p>
<h3>{t('use.user_content.title')}</h3>
<p>{t('use.user_content.description')}</p>
<h2>{t('personal_data.title')}</h2>
<h3>{t('personal_data.collect.title')}</h3>
<p>
<Trans
i18nKey="personal_data.collect.description"
components={{ a: <Link href={route('privacy').url} /> }}
/>
</p>
<h3>{t('personal_data.suppress.title')}</h3>
<p>{t('personal_data.suppress.description')}</p>
<h2>{t('responsibility_warranty.title')}</h2>
<h3>{t('responsibility_warranty.responsibility.title')}</h3>
<p>{t('responsibility_warranty.responsibility.description')}</p>
<h3>{t('responsibility_warranty.warranty.title')}</h3>
<p>{t('responsibility_warranty.warranty.description')}</p>
<h2>{t('terms_changes.title')}</h2>
<p>{t('terms_changes.description')}</p>
<h2>{t('cancel.title')}</h2>
<p>{t('cancel.description')}</p>
</LegalContentLayout>
);
}

View File

@@ -5,9 +5,9 @@ const AppsController = () => import('#controllers/apps_controller');
* All routes for both logged and guest users
*/
router.group(() => {
router.get('/', [AppsController, 'index']).as('home');
router.get('/privacy', () => 'privacy').as('privacy');
router.get('/terms', () => 'terms').as('terms');
router.on('/').renderInertia('home').as('home');
router.on('/terms').renderInertia('terms').as('terms');
router.on('/privacy').renderInertia('privacy').as('privacy');
router
.post('/user/theme', [AppsController, 'updateUserTheme'])