Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion front/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
import "./.next/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
10 changes: 7 additions & 3 deletions front/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import "./globals.css";
import { FooterComponent, HeaderComponent } from "../layouts";
import { CookiesConsentProvider, CookiesBanner } from "../common/cookies";

interface Props {
children: React.ReactNode;
Expand All @@ -14,9 +15,12 @@ const RootLayout = (props: Props) => {
className="bg-base-200 text-base-content flex min-h-screen flex-col"
suppressHydrationWarning
>
<HeaderComponent />
<main className="flex grow flex-col">{children}</main>
<FooterComponent />
<CookiesConsentProvider>
<HeaderComponent />
<main className="flex grow flex-col">{children}</main>
<FooterComponent />
<CookiesBanner />
</CookiesConsentProvider>
</body>
</html>
);
Expand Down
38 changes: 38 additions & 0 deletions front/src/common/cookies/cookies-banner.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";

import Link from "next/link";
import React from "react";
import { useCookiesConsent } from "./cookies-consent.context";

export const CookiesBanner: React.FC = () => {
const { consent, acceptCookies, rejectCookies } = useCookiesConsent();

if (consent !== null) {
return null;
}

return (
<div className="fixed inset-x-0 bottom-0 z-50 p-4">
<div className="alert bg-base-100 border-accent mx-auto max-w-3xl flex-col gap-3 border shadow-lg sm:flex-row sm:gap-4">
<p className="text-sm text-center sm:text-left">
Utilizamos cookies analíticas para mejorar tu experiencia. Puedes
aceptar o rechazar su uso.{" "}
<Link href="/politica-cookies" className="link link-accent">
Política de Cookies
</Link>
</p>
<div className="flex shrink-0 gap-2">
<button className="btn btn-accent btn-sm" onClick={acceptCookies}>
Aceptar
</button>
<button
className="btn btn-outline btn-sm"
onClick={rejectCookies}
>
Rechazar
</button>
</div>
</div>
</div>
);
};
61 changes: 61 additions & 0 deletions front/src/common/cookies/cookies-consent.context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client";

import React, { createContext, useContext, useState, useEffect } from "react";

type CookiesConsent = "accepted" | "rejected" | null;

interface CookiesConsentContextType {
consent: CookiesConsent;
acceptCookies: () => void;
rejectCookies: () => void;
resetCookies: () => void;
}

const STORAGE_KEY = "cookies-consent";

const CookiesConsentContext = createContext<CookiesConsentContextType>({
consent: null,
acceptCookies: () => {},
rejectCookies: () => {},
resetCookies: () => {},
});

export const useCookiesConsent = () => useContext(CookiesConsentContext);

interface Props {
children: React.ReactNode;
}

export const CookiesConsentProvider: React.FC<Props> = ({ children }) => {
const [consent, setConsent] = useState<CookiesConsent>(null);

useEffect(() => {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored === "accepted" || stored === "rejected") {
setConsent(stored);
}
}, []);

const acceptCookies = () => {
localStorage.setItem(STORAGE_KEY, "accepted");
setConsent("accepted");
};

const rejectCookies = () => {
localStorage.setItem(STORAGE_KEY, "rejected");
setConsent("rejected");
};

const resetCookies = () => {
localStorage.removeItem(STORAGE_KEY);
setConsent(null);
};

return (
<CookiesConsentContext.Provider
value={{ consent, acceptCookies, rejectCookies, resetCookies }}
>
{children}
</CookiesConsentContext.Provider>
);
};
17 changes: 17 additions & 0 deletions front/src/common/cookies/cookies-reset-button.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use client";

import React from "react";
import { useCookiesConsent } from "./cookies-consent.context";

export const CookiesResetButton: React.FC = () => {
const { resetCookies } = useCookiesConsent();

return (
<button
onClick={resetCookies}
className="link-accessible text-sm font-normal"
>
Configurar cookies
</button>
);
};
3 changes: 3 additions & 0 deletions front/src/common/cookies/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { CookiesConsentProvider, useCookiesConsent } from "./cookies-consent.context";
export { CookiesBanner } from "./cookies-banner.component";
export { CookiesResetButton } from "./cookies-reset-button.component";
4 changes: 3 additions & 1 deletion front/src/layouts/footer.component.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Link from "next/link";
import { FC } from "react";
import { CookiesResetButton } from "../common/cookies";

export const FooterComponent: FC = () => {
return (
Expand All @@ -13,7 +14,7 @@ export const FooterComponent: FC = () => {
Embalses por provincias
</Link>

<div className="flex justify-between gap-2">
<div className="flex flex-wrap justify-center gap-x-3 gap-y-1">
<Link
href="/aviso-legal"
className="link-accessible text-sm font-normal"
Expand All @@ -26,6 +27,7 @@ export const FooterComponent: FC = () => {
>
Política de cookies
</Link>
<CookiesResetButton />
</div>
</div>

Expand Down