Skip to content

Commit 43be313

Browse files
committed
feat: Adjust footer and add privacy page
1 parent 02c39f1 commit 43be313

7 files changed

Lines changed: 354 additions & 9 deletions

File tree

-22.9 KB
Loading

frontend/src/Router.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import VerifyPage from "@pages/Verify";
1010
import ForgotPasswordPage from "@pages/ForgotPassword";
1111
import ResetPasswordPage from "@pages/ResetPassword";
1212
import HelpPage from "@pages/Help";
13+
import PrivacyPage from "@pages/Privacy";
1314
import DashboardPage from "@pages/Dashboard";
1415
import ItinerariesPage from "@pages/itineraries/Itineraries";
1516
import ItineraryDetailPage from "@pages/itineraries/ItineraryDetail";
@@ -104,6 +105,7 @@ export default function Router() {
104105
<Route path="/forgot-password" element={<ForgotPasswordPage />} />
105106
<Route path="/reset-password" element={<ResetPasswordPage />} />
106107
<Route path="/help" element={<HelpPage />} />
108+
<Route path="/privacy" element={<PrivacyPage />} />
107109
<Route path="/share/:token" element={<SharedItineraryPage />} />
108110

109111
{/* Private routes */}

frontend/src/components/shared/Footer.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import styles from "@styles/components/shared/Footer.module.css";
2+
import { NavLink } from "react-router";
23

34
import { GithubIcon, LinkedinIcon } from "lucide-react";
45

@@ -16,7 +17,9 @@ export default function Footer() {
1617
</p>
1718
</div>
1819
<div className={styles.right}>
19-
<span className={styles.author}>Creado por <strong>CuB1z</strong></span>
20+
<span className={styles.author}>
21+
Creado por <span className={styles.authorName}>CuB1z</span>
22+
</span>
2023
<div className={styles.socials}>
2124
<Button
2225
style={["tool"]}
@@ -35,10 +38,19 @@ export default function Footer() {
3538
</div>
3639
</div>
3740
</div>
38-
<Divider maxWidth={1200} />
39-
<p className={styles.copyright}>
40-
©2025 TripFlow. Todos los derechos reservados.
41-
</p>
41+
<Divider maxWidth="100%" />
42+
<div className={styles.footer_bottom}>
43+
<p className={styles.copyright}>
44+
©2026 TripFlow.
45+
<br />
46+
Todos los derechos reservados.
47+
</p>
48+
<nav className={styles.legalLinks} aria-label="Enlaces legales">
49+
<NavLink to="/help" className={styles.legalLink}>Ayuda</NavLink>
50+
<span className={styles.separator}></span>
51+
<NavLink to="/privacy" className={styles.legalLink}>Privacidad</NavLink>
52+
</nav>
53+
</div>
4254
</footer>
4355
);
4456
}

frontend/src/pages/Privacy.tsx

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import styles from "@styles/pages/Privacy.module.css";
2+
3+
import Layout from "@/layouts/Layout";
4+
import Badge from "@/components/shared/Badge";
5+
6+
import { ShieldCheckIcon } from "lucide-react";
7+
8+
const LAST_UPDATE = "13 de abril de 2026";
9+
10+
const PRIVACY_SECTIONS = [
11+
{
12+
title: "1. Responsable del tratamiento",
13+
paragraphs: [
14+
"TripFlow es responsable del tratamiento de los datos personales recopilados a través de esta plataforma para prestar servicios de planificación, colaboración y seguimiento de itinerarios de viaje.",
15+
"Para consultas sobre privacidad puedes usar los canales de soporte disponibles dentro de la plataforma.",
16+
],
17+
},
18+
{
19+
title: "2. Datos que recopilamos",
20+
paragraphs: [
21+
"Recopilamos información de registro como nombre, correo electrónico y credenciales cifradas. También podemos almacenar preferencias de viaje, itinerarios, ubicaciones agregadas por ti, configuraciones de cuenta y metadatos técnicos de uso.",
22+
"Si habilitas funciones colaborativas, guardamos la relación entre participantes, roles y acciones sobre el contenido compartido para mantener trazabilidad y seguridad.",
23+
],
24+
},
25+
{
26+
title: "3. Finalidades del tratamiento",
27+
paragraphs: [
28+
"Usamos tus datos para crear y administrar tu cuenta, sincronizar itinerarios, enviar notificaciones relacionadas con el servicio, resolver incidencias y mejorar el rendimiento de la aplicación.",
29+
"También tratamos información técnica para prevenir fraude, abusos, accesos no autorizados y para cumplir obligaciones legales aplicables.",
30+
],
31+
},
32+
{
33+
title: "4. Base legal y conservación",
34+
paragraphs: [
35+
"La base legal principal es la ejecución del servicio solicitado y, cuando corresponde, tu consentimiento para funciones opcionales.",
36+
"Conservamos los datos mientras la cuenta permanezca activa o durante los plazos necesarios para cumplir obligaciones legales, resolver disputas y proteger nuestros derechos.",
37+
],
38+
},
39+
{
40+
title: "5. Compartición de datos",
41+
paragraphs: [
42+
"No vendemos tus datos personales. Solo compartimos información con proveedores que prestan servicios esenciales (alojamiento, notificaciones, analítica operativa) bajo acuerdos de confidencialidad y seguridad.",
43+
"Podemos revelar datos cuando exista una obligación legal válida o para proteger la seguridad de la plataforma y de sus usuarios.",
44+
],
45+
},
46+
{
47+
title: "6. Tus derechos",
48+
paragraphs: [
49+
"Puedes solicitar acceso, rectificación, supresión, oposición, limitación del tratamiento y portabilidad de tus datos, de acuerdo con la normativa aplicable.",
50+
"También puedes retirar tu consentimiento para tratamientos opcionales en cualquier momento, sin afectar la licitud del tratamiento previo.",
51+
],
52+
},
53+
{
54+
title: "7. Seguridad",
55+
paragraphs: [
56+
"Aplicamos medidas técnicas y organizativas razonables para proteger la confidencialidad, integridad y disponibilidad de la información.",
57+
"Aunque ningún sistema es completamente infalible, trabajamos de forma continua para reducir riesgos y responder rápidamente ante incidentes.",
58+
],
59+
},
60+
{
61+
title: "8. Cookies y tecnologías similares",
62+
paragraphs: [
63+
"Utilizamos cookies y almacenamiento local para autenticar sesiones, recordar preferencias y mejorar la experiencia de uso.",
64+
"Puedes gestionar estas tecnologías desde la configuración de tu navegador. Algunas funciones pueden verse limitadas si las desactivas.",
65+
],
66+
},
67+
{
68+
title: "9. Cambios en esta política",
69+
paragraphs: [
70+
"Podemos actualizar esta Política de Privacidad para reflejar mejoras del servicio o cambios normativos. Publicaremos la fecha de última actualización en esta misma página.",
71+
"Si los cambios son relevantes, te lo comunicaremos por los canales disponibles en la plataforma.",
72+
],
73+
},
74+
];
75+
76+
export default function PrivacyPage() {
77+
return (
78+
<Layout>
79+
<div className={styles.container}>
80+
<section className={styles.section} aria-labelledby="privacy-title">
81+
<div className={styles.headerBlock}>
82+
<div className={styles.headerTopRow}>
83+
<h2 className={styles.sectionTitle}>
84+
Política de Privacidad
85+
</h2>
86+
<div className={styles.privacyChip}>
87+
<Badge style="default">
88+
<>
89+
<ShieldCheckIcon size={16} />
90+
Protección de datos
91+
</>
92+
</Badge>
93+
</div>
94+
</div>
95+
<p className={styles.sectionDescription}>
96+
Esta política explica qué datos tratamos, por qué los necesitamos y qué opciones tienes
97+
para controlar tu información dentro de TripFlow.
98+
</p>
99+
<p className={styles.lastUpdate}>Última actualización: {LAST_UPDATE}</p>
100+
</div>
101+
102+
<div className={styles.contentBlocks}>
103+
{PRIVACY_SECTIONS.map((section) => (
104+
<article key={section.title} className={styles.contentCard}>
105+
<h2 className={styles.cardTitle}>{section.title}</h2>
106+
<div className={styles.cardBody}>
107+
{section.paragraphs.map((paragraph) => (
108+
<p key={paragraph}>{paragraph}</p>
109+
))}
110+
</div>
111+
</article>
112+
))}
113+
</div>
114+
</section>
115+
</div>
116+
</Layout>
117+
);
118+
}

frontend/src/styles/components/sections/Guide.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
}
6363

6464
.guideImage {
65-
margin-top: var(--space-larger);
65+
margin-top: var(--space-largest);
6666

6767
.imageContainer {
6868
.image {

frontend/src/styles/components/shared/Footer.module.css

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
flex-direction: column;
99
align-items: center;
1010
justify-content: center;
11-
gap: var(--space-larger);
11+
gap: var(--space-xxxl);
1212

1313
background-color: var(--bg-primary-alpha);
1414
backdrop-filter: blur(10px);
@@ -37,12 +37,25 @@
3737

3838
.left {
3939
.description {
40-
max-width: 350px;
40+
max-width: 420px;
4141
color: var(--text-tertiary);
42+
font-weight: var(--font-weight-light);
43+
text-wrap: pretty;
4244
}
4345
}
4446

4547
.right {
48+
.author {
49+
color: var(--text-tertiary);
50+
font-size: var(--font-size-sm);
51+
line-height: 1.2;
52+
}
53+
54+
.authorName {
55+
color: var(--primary);
56+
font-weight: var(--font-weight-bold);
57+
}
58+
4659
.socials {
4760
width: 100%;
4861
display: flex;
@@ -52,9 +65,46 @@
5265
}
5366
}
5467

68+
.footer_bottom {
69+
width: 100%;
70+
display: flex;
71+
align-items: center;
72+
justify-content: space-between;
73+
gap: var(--space-lg);
74+
}
75+
5576
.copyright {
5677
color: var(--text-tertiary);
57-
text-align: center;
78+
font-size: var(--font-size-sm);
79+
margin: 0;
80+
text-wrap: pretty;
81+
}
82+
83+
.legalLinks {
84+
display: flex;
85+
align-items: center;
86+
justify-content: flex-end;
87+
gap: 8px;
88+
89+
.legalLink {
90+
color: var(--text-tertiary);
91+
font-size: var(--font-size-sm);
92+
line-height: 1;
93+
text-decoration: none;
94+
transition: color 0.2s ease;
95+
96+
@media (hover: hover) {
97+
&:hover {
98+
color: var(--text-secondary);
99+
}
100+
}
101+
}
102+
103+
.separator {
104+
color: var(--text-muted);
105+
font-size: var(--font-size-sm);
106+
line-height: 1;
107+
}
58108
}
59109
}
60110

@@ -81,8 +131,21 @@
81131
}
82132
}
83133

134+
.footer_bottom {
135+
flex-direction: column-reverse;
136+
align-items: center;
137+
justify-content: center;
138+
gap: var(--space-xxl);
139+
}
140+
84141
.copyright {
85142
word-break: break-word;
143+
text-align: center;
144+
}
145+
146+
.legalLinks {
147+
flex-wrap: wrap;
148+
justify-content: center;
86149
}
87150
}
88151
}

0 commit comments

Comments
 (0)