feat: Add visual permission cards and intro text to the Policies page, including new icons, translations, and styling adjustments.

This commit is contained in:
Van Leemput Dayron
2025-12-06 16:30:51 +01:00
parent b148b4d90e
commit 00999578f0
2 changed files with 79 additions and 16 deletions

View File

@@ -1,12 +1,12 @@
import { motion } from 'framer-motion';
import { useLanguage } from '../contexts/LanguageContext';
import { Link } from 'react-router-dom';
import { ArrowLeft, ExternalLink } from 'lucide-react';
import { ArrowLeft, ExternalLink, Camera, MapPin, Bell } from 'lucide-react';
const Policies = () => {
const { t } = useLanguage();
const sections = [1, 2, 3, 4, 5, 6];
const sections = [2, 3, 4, 5, 6]; // Sections after the permission cards (1 is before)
const containerVariants = {
hidden: { opacity: 0 },
@@ -50,18 +50,63 @@ const Policies = () => {
>
{/* Header */}
<motion.div variants={sectionVariants} style={{ marginBottom: '3rem', textAlign: 'center' }}>
{/* Removed large icon as per screenshot text-focus, keeping it simple or small if needed. Screenshot has just text headers usually, but I'll keep it clean. */}
<h1 style={{ fontSize: '2rem', marginBottom: '2rem', fontWeight: 'bold' }}>{t('policies.title')}</h1>
<h1 style={{ fontSize: '2.5rem', marginBottom: '1rem', fontWeight: 'bold' }}>{t('policies.title')}</h1>
<p style={{ fontSize: '1.2rem', opacity: 0.7 }}>{t('policies.intro')}</p>
</motion.div>
{/* Sections Loop */}
{/* Section 1: Collection (Text) */}
<motion.div variants={sectionVariants} className="policy-section" style={{ marginBottom: '2.5rem' }}>
<h2 style={{ fontSize: '1.5rem', marginBottom: '1rem', fontWeight: '700' }}>
{t('policies.section.1.title')}
</h2>
<p style={{ lineHeight: '1.8', opacity: 0.9, fontSize: '1rem' }}>
{t('policies.section.1.content')}
</p>
</motion.div>
{/* Visual Permission Cards */}
<motion.div variants={sectionVariants} style={{ marginBottom: '4rem' }}>
<h3 style={{ fontSize: '1.2rem', marginBottom: '1.5rem', opacity: 0.8 }}>{t('policies.permissions.title')}</h3>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: '1.5rem' }}>
{/* Camera */}
<div style={{ background: 'var(--card-bg, rgba(255,255,255,0.05))', padding: '1.5rem', borderRadius: '1rem', border: '1px solid var(--border-color, rgba(255, 255, 255, 0.1))' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '1rem', color: 'var(--primary-color)' }}>
<Camera size={24} />
<h4 style={{ margin: 0, fontSize: '1.1rem' }}>{t('policies.data.camera')}</h4>
</div>
<p style={{ opacity: 0.7, fontSize: '0.9rem', lineHeight: '1.5' }}>{t('policies.data.camera.desc')}</p>
</div>
{/* GPS */}
<div style={{ background: 'var(--card-bg, rgba(255,255,255,0.05))', padding: '1.5rem', borderRadius: '1rem', border: '1px solid var(--border-color, rgba(255, 255, 255, 0.1))' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '1rem', color: 'var(--primary-color)' }}>
<MapPin size={24} />
<h4 style={{ margin: 0, fontSize: '1.1rem' }}>{t('policies.data.gps')}</h4>
</div>
<p style={{ opacity: 0.7, fontSize: '0.9rem', lineHeight: '1.5' }}>{t('policies.data.gps.desc')}</p>
</div>
{/* Notifications */}
<div style={{ background: 'var(--card-bg, rgba(255,255,255,0.05))', padding: '1.5rem', borderRadius: '1rem', border: '1px solid var(--border-color, rgba(255, 255, 255, 0.1))' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '1rem', color: 'var(--primary-color)' }}>
<Bell size={24} />
<h4 style={{ margin: 0, fontSize: '1.1rem' }}>{t('policies.data.notif')}</h4>
</div>
<p style={{ opacity: 0.7, fontSize: '0.9rem', lineHeight: '1.5' }}>{t('policies.data.notif.desc')}</p>
</div>
</div>
</motion.div>
{/* Remaining Sections (Loop) */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '2.5rem' }}>
{sections.map((num) => (
<motion.div key={num} variants={sectionVariants} className="policy-section">
<h2 style={{ fontSize: '1.25rem', marginBottom: '0.75rem', fontWeight: '700' }}>
<h2 style={{ fontSize: '1.5rem', marginBottom: '1rem', fontWeight: '700' }}>
{t(`policies.section.${num}.title`)}
</h2>
<p style={{ lineHeight: '1.6', opacity: 0.8, fontSize: '1rem' }}>
<p style={{ lineHeight: '1.8', opacity: 0.9, fontSize: '1rem' }}>
{t(`policies.section.${num}.content`)}
</p>
</motion.div>
@@ -69,7 +114,7 @@ const Policies = () => {
</div>
{/* Google Policy Button */}
<motion.div variants={sectionVariants} style={{ marginTop: '4rem', textAlign: 'center' }}>
<motion.div variants={sectionVariants} style={{ marginTop: '5rem', textAlign: 'center' }}>
<a
href="https://policies.google.com/privacy"
target="_blank"
@@ -78,16 +123,16 @@ const Policies = () => {
display: 'inline-flex',
alignItems: 'center',
gap: '10px',
background: '#00695c', // Teal color like in screenshot
color: 'white',
padding: '12px 24px',
borderRadius: '8px',
background: 'transparent',
border: '1px solid var(--primary-color)',
color: 'var(--primary-color)',
padding: '12px 30px',
borderRadius: '50px',
textDecoration: 'none',
fontWeight: '500',
width: '100%',
justifyContent: 'center',
maxWidth: '400px'
fontWeight: '600',
transition: 'all 0.3s ease'
}}
className="hover-scale"
>
<ExternalLink size={18} />
{t('policies.googleBtn')}

View File

@@ -177,10 +177,19 @@ const translations = {
// Policies Page
'policies.back': 'Retour',
'policies.title': 'Politiques de confidentialité',
'policies.intro': 'Votre vie privée est importante pour nous. Voici comment nous protégeons vos données.',
'policies.section.1.title': 'Collecte d\'informations',
'policies.section.1.content': 'Nous collectons des informations que vous nous fournissez directement, comme votre nom, adresse e-mail et préférences de voyage.',
'policies.permissions.title': 'Permissions Appareil',
'policies.data.camera': 'Caméra & Galerie',
'policies.data.camera.desc': 'Pour ajouter des photos aux souvenirs ou scanner des factures.',
'policies.data.gps': 'Localisation (GPS)',
'policies.data.gps.desc': 'Pour la carte interactive et les suggestions d\'activités à proximité.',
'policies.data.notif': 'Notifications',
'policies.data.notif.desc': 'Pour vous alerter des nouveaux messages, dépenses ou changements de programme.',
'policies.section.2.title': 'Utilisation des données',
'policies.section.2.content': 'Vos données sont utilisées pour améliorer votre expérience utilisateur et vous proposer des recommandations personnalisées.',
@@ -358,10 +367,19 @@ const translations = {
// Policies Page
'policies.back': 'Back',
'policies.title': 'Privacy Policy',
'policies.intro': 'Your privacy is important to us. Here is how we protect your data.',
'policies.section.1.title': 'Information Collection',
'policies.section.1.content': 'We collect information that you provide directly to us, such as your name, email address, and travel preferences.',
'policies.permissions.title': 'Device Permissions',
'policies.data.camera': 'Camera & Gallery',
'policies.data.camera.desc': 'To add photos to memories or scan receipts.',
'policies.data.gps': 'Location (GPS)',
'policies.data.gps.desc': 'For the interactive map and nearby activity suggestions.',
'policies.data.notif': 'Notifications',
'policies.data.notif.desc': 'To alert you of new messages, expenses, or schedule changes.',
'policies.section.2.title': 'Data Usage',
'policies.section.2.content': 'Your data is used to improve your user experience and offer you personalized recommendations.',