Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/HNG-33-cookie-consent-settings #246

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
47 changes: 47 additions & 0 deletions app/components/ui/CookieConsent/CookieConsent.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.CookieConsent{
background: rgba(20, 20, 20, 1);

}

*{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already in global css

box-sizing: border-box;
}
.modal{
max-width: 791px;
height: auto;
width: 50%;
max-height: 90vh;
overflow-y: auto;
}

.modal_content{
padding: 0px 24px;
}

.roboto{
font-family: Roboto;
font-size: 24px;
font-weight: 700;
line-height: 28.13px;
text-align: left;
}

.inter{
font-family: Inter;
font-size: 16px;
font-weight: 400;
line-height: 19.36px;
text-align: left;
}

.cookie_info{
display: flex;
justify-content: space-between;
padding: 24px 0px;


}

.hidden{
display: none;
}
69 changes: 69 additions & 0 deletions app/components/ui/CookieConsent/CookieConsent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, {useState} from "react";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to import react, just useState is fine

import styles from './CookieConsent.module.css';
import CookieSettings from "./CookieSettings";

export default function CookieConsent(){
const [isExpanded, setIsExpanded] = useState(false);

const toggleExpand = () => {
setIsExpanded(!isExpanded);
};

return (
<div className='fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50"'>
<div className={`${styles.modal} bg-white p-6 rounded-lg shadow-xl max-w-3xl w-full m-10`}>
<div className={`mb-6`}>
<p className="text-xl font-semibold">Customize cookies</p>
<p className="text-sm text-gray-600 mt-2 mb-10">
Cookies are small text files that are stored on your device when you visit websites.
They are used to remember information about you, such as your login details, preferences, and browsing history.
Cookies help enhance your browsing experience by allowing websites to remember your actions and preferences over time,
ensuring that you don’t have to re-enter information each time you visit a site.
They also help website owners analyze traffic and user behavior to improve their services.
Read our <a href="#" className="text-orange-600 hover:underline" target="_blank">Privacy Policy</a> for more details
</p>
<div className="relative mb-2">
<div className="flex justify-between items-start">
<div className="pr-8 flex-grow">
<div className='flex justify-between items-center mb-2'>
<p className="font-medium">Strictly necessary</p>
<div
className="ml-4"
onClick={toggleExpand}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
toggleExpand();
e.preventDefault()
}
}}
Comment on lines +35 to +40
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract this into a function, then call it here

aria-expanded={isExpanded}
>
<img
src={isExpanded ? '/chevron-down.svg' : '/chevron-up.svg'}
alt={isExpanded ? 'Collapse' : 'Expand'}
/>
</div>
</div>
<p className={`text-sm text-gray-600 ${isExpanded ? '' : 'hidden'}`}>
These cookies are essential for the website to function properly.
They enable basic functions like page navigation, secure login,
and access to protected areas of the site. Without these cookies,
the website cannot perform properly.
</p>
<hr className="my-6" />
</div>
<p className="text-gray-500 text-sm whitespace-nowrap">Always Enabled</p>
</div>
</div>
<CookieSettings/>
<div className="flex justify-end mt-6">
<button className="bg-orange-500 text-white py-2 px-4 rounded-lg">Save & Accept</button>
</div>
</div>
</div>
</div>

)
}
118 changes: 118 additions & 0 deletions app/components/ui/CookieConsent/CookieSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React, { useState } from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't import the entire React, just import what you need, e.g FC


interface CookieSetting {
title: string;
description: string;
id: string;
}

interface CookiePreferenceProps extends CookieSetting {
isExpanded: boolean;
onToggle: () => void;
isChecked: boolean;
onCheckChange: (checked: boolean) => void;
}

const CookiePreference: React.FC<CookiePreferenceProps> = ({
title,
description,
isExpanded,
onToggle,
id,
isChecked,
onCheckChange
}) => {
return (
<div className="mb-6">
<div className="flex justify-between items-start">
<div className="flex-grow pr-20">
<div className="flex justify-between items-center mb-2">
<p className="text-lg font-medium">{title}</p>
<div
className="ml-4 cursor-pointer"
onClick={onToggle}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
onToggle();
e.preventDefault()
}
}}
Comment on lines +37 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract into a function

aria-expanded={isExpanded}
>
<img
src={isExpanded ? '/chevron-down.svg' : '/chevron-up.svg'}
alt={isExpanded ? 'Collapse' : 'Expand'}
/>
</div>
</div>
<p className={`text-sm text-gray-600 ${isExpanded ? '' : 'hidden'}`}>
{description}
</p>
<hr className="my-6" />
</div>
<label className="relative inline-flex items-center cursor-pointer" htmlFor={id}>
<input
type="checkbox"
className="sr-only peer"
id={id}
checked={isChecked}
onChange={(e) => onCheckChange(e.target.checked)}
/>
<div className="w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-orange-500"></div>
</label>
</div>
</div>
);
};

const CookieSettings: React.FC = () => {
const [expandedIndex, setExpandedIndex] = useState<number | null>(null);
const [checkedStates, setCheckedStates] = useState<{ [key: string]: boolean }>({});

const cookieSettings = [
{
title: "Performance Cookies",
id: "pc",
description: "These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site."
},
{
title: "Functional Cookies",
id: "fc",
description: "These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages."
},
{
title: "Targeting Cookies",
id: "tc",
description: "These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites."
}
];

const handleToggle = (index: number) => {
setExpandedIndex(expandedIndex === index ? null : index);
};

const handleCheckChange = (id: string, checked: boolean) => {
setCheckedStates(prev => ({ ...prev, [id]: checked }));
};

return (
<div>
{cookieSettings.map((setting, index) => (
<CookiePreference
key={index}
title={setting.title}
description={setting.description}
isExpanded={expandedIndex === index}
onToggle={() => handleToggle(index)}
id={setting.id}
isChecked={checkedStates[setting.id] || false}
onCheckChange={(checked) => handleCheckChange(setting.id, checked)}
/>
))}
</div>
);
};

export default CookieSettings;
2 changes: 2 additions & 0 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { MetaFunction } from "@remix-run/node";
import { Button } from "~/components/ui/button";
import CardPlatform from "~/components/ui/card/card-platform";
import CookieConsent from "~/components/ui/CookieConsent/CookieConsent";

export const meta: MetaFunction = () => {
return [
Expand Down Expand Up @@ -54,6 +55,7 @@ export default function Index() {
</a>
</li>
</ul>
<CookieConsent/>
</div>
);
}