Skip to content

Commit

Permalink
Merge pull request #21 from betagouv/refacto-widgets-dsfr
Browse files Browse the repository at this point in the history
Refacto widgets dsfr
  • Loading branch information
AlexTensorer authored Dec 6, 2024
2 parents d9a1a8e + 6c86d93 commit c81ff89
Show file tree
Hide file tree
Showing 14 changed files with 883 additions and 681 deletions.
13 changes: 11 additions & 2 deletions api/src/controllers/iframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ router.get("/widget/:widgetId/msearch", async (req: Request, res: Response, next
} as { [key: string]: any };

if (query.data.domain) where.domain = Array.isArray(query.data.domain) ? { $in: query.data.domain } : query.data.domain;
if (query.data.department) where.departmentName = Array.isArray(query.data.department) ? { $in: query.data.department } : query.data.department;

if (query.data.department === "none") where.$or = [{ departmentName: "" }, { departmentName: null }];
else if (query.data.department) where.departmentName = Array.isArray(query.data.department) ? { $in: query.data.department } : query.data.department;

if (query.data.organization) where.organizationName = Array.isArray(query.data.organization) ? { $in: query.data.organization } : query.data.organization;
if (query.data.schedule) where.schedule = Array.isArray(query.data.schedule) ? { $in: query.data.schedule } : query.data.schedule;
if (query.data.action) where.organizationActions = Array.isArray(query.data.action) ? { $in: query.data.action } : query.data.action;
Expand Down Expand Up @@ -157,7 +160,13 @@ router.get("/widget/:widgetId/msearch", async (req: Request, res: Response, next
if (key !== "domain" && query.data.domain) filters.domain = Array.isArray(query.data.domain) ? { $in: query.data.domain } : query.data.domain;
if (key !== "organization" && query.data.organization)
filters.organizationName = Array.isArray(query.data.organization) ? { $in: query.data.organization } : query.data.organization;
if (key !== "department" && query.data.department) filters.departmentName = Array.isArray(query.data.department) ? { $in: query.data.department } : query.data.department;
if (key !== "department" && query.data.department) {
if (query.data.department === "none") {
filters.departmentName = { $in: ["", null] };
} else {
filters.departmentName = Array.isArray(query.data.department) ? { $in: query.data.department } : query.data.department;
}
}
if (key !== "schedule" && query.data.schedule) filters.schedule = Array.isArray(query.data.schedule) ? { $in: query.data.schedule } : query.data.schedule;
if (key !== "action" && query.data.action) filters.organizationActions = Array.isArray(query.data.action) ? { $in: query.data.action } : query.data.action;
if (key !== "beneficiary" && query.data.beneficiary)
Expand Down
4 changes: 2 additions & 2 deletions app/src/scenes/widget/Edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ const Frame = ({ widget }) => {
};

return (
<div className="bg-white p-12 space-y-10 shadow-lg">
<div className="bg-white p-16 space-y-10 shadow-lg">
<div className="flex flex-col gap-2">
<h2 className="text-2xl font-bold">Aperçu du widget</h2>
<span>Enregistrez le widget pour mettre à jour l'aperçu</span>
Expand Down Expand Up @@ -625,7 +625,7 @@ const IFRAMES = {

const JVA_LOGO = `<div style="padding:10px; display:flex;">
<img src="https://apicivique.s3.eu-west-3.amazonaws.com/jvalogo.svg"/>
<div style="color:#A5A5A5; font-style:normal; font-size:13px; padding:8px;">Proposé par la plateforme publique du bénévolat
<div style="color:#666666; font-style:normal; font-size:13px; padding:8px;">Proposé par la plateforme publique du bénévolat
<a href="https://www.jeveuxaider.gouv.fr/" target="_blank">JeVeuxAider.gouv.fr</a>
</div>
</div>`;
Expand Down
53 changes: 31 additions & 22 deletions widget-benevolat/components/card.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,54 @@
import React from "react";
import Image from "next/image";
import iso from "i18n-iso-countries";
import { RiArrowRightSLine } from "react-icons/ri";
import { RiBuildingFill } from "react-icons/ri";

import { DOMAINES } from "../config";

const Card = ({ widget, mission, color, request }) => {
const Card = ({ widget, mission, request }) => {
if (!mission) return null;

return (
<a
tabIndex={0}
href={mission.url}
target="_blank"
className="border min-h-[500px] w-full max-w-[90%] mx-auto flex flex-col border-neutral-grey-950 rounded-xl overflow-hidden focus:outline-none focus-visible:ring focus-visible:ring-blue-800"
className={`${
widget.style === "carousel" ? "max-w-[336px] max-h-[456px]" : "w-full"
} group border h-full mx-auto flex flex-col border-neutral-grey-950 overflow-hidden focus:outline-none focus-visible:ring focus-visible:ring-blue-800 hover:shadow-lg transition-shadow duration-300`}
>
<div className="h-48">
<Image src={mission.domainLogo} alt={mission.title} priority={true} className="w-full h-full object-cover" width={500} height={500} />
<div className="h-[200px] overflow-hidden">
<Image
src={mission.domainLogo}
alt={mission.title}
priority={true}
className="w-full h-full object-cover transition-transform duration-300 group-hover:scale-110"
width={500}
height={500}
/>
</div>
<div className="flex-1 flex flex-col p-6 justify-between">
<div className="h-40">
<div className="w-full text-center mb-1">
<span name="tracker_counter" data-id={mission._id} data-publisher={widget.fromPublisherId.toString()} data-source={widget._id.toString()} data-request={request} />

<div className="flex-1 flex flex-col p-6 justify-between gap-4">
<div className="flex flex-col gap-3">
<span className="text-xs bg-[#EEE] w-fit py-0.5 px-2 rounded-full">{DOMAINES[mission.domain] || mission.domain}</span>
<div className="flex gap-2 text-[#666]">
<RiBuildingFill />
<span className="text-xs line-clamp-2">{mission.organizationName}</span>
</div>
<h2 className="font-semibold line-clamp-3 my-2 text-xl">{mission.title}</h2>
<span className="text-sm truncate text-default-grey">
{mission.remote === "full" ? "À distance" : `${mission.city} ${mission.postalCode}${mission.country !== "FR" ? `- ${iso.getName(mission.country, "fr")}` : ""}`}
</span>
</div>
<div className="flex flex-col">
<span className="uppercase font-semibold text-sm whitespace-nowrap truncate tracking-wider" style={{ color }}>
{DOMAINES[mission.domain] || mission.domain}

<div className="flex flex-col gap-3">
<h2 className="font-semibold line-clamp-3 text-xl group-hover:text-[#000091] transition-colors duration-300">{mission.title}</h2>
<span className="text-sm truncate text-[#3A3A3A]">
{mission.remote === "full" ? "À distance" : `${mission.city} ${mission.postalCode}${mission.country !== "FR" ? `- ${iso.getName(mission.country, "fr")}` : ""}`}
</span>
<p className="text-mention-grey line-clamp-2 text-sm h-10">
Par
<span className="font-semibold ml-1">{mission.organizationName}</span>
</p>
<div className="w-full text-center mb-1">
<span name="tracker_counter" data-id={mission._id} data-publisher={widget.fromPublisherId.toString()} data-source={widget._id.toString()} data-request={request} />
</div>
</div>
<div className="flex justify-between items-center">

<div className="flex items-center">
<span className="text-xs text-mention-grey">{`${mission.places} ${mission.places > 1 ? "bénévoles recherchés" : "bénévole recherché"}`}</span>
<RiArrowRightSLine aria-label="Accéder à la mission" className="text-3xl" style={{ color }} />
</div>
</div>
</a>
Expand Down
90 changes: 47 additions & 43 deletions widget-benevolat/components/carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,49 +41,57 @@ export const Carousel = ({ widget, missions, color, request }) => {
}

return (
<main className="w-full relative">
<div className="overflow-hidden">
<div className="flex transition-transform duration-500 ease-in-out" style={{ transform: `translateX(-${currentSlide * (100 / slidesToShow)}%)` }}>
{missions.slice(0, 60).map((mission, i) => (
<div role="group" key={i} id={mission._id} aria-labelledby={mission._id} className={`flex-shrink-0 w-full sm:w-1/2 lg:w-1/3 px-2`}>
<Card widget={widget} mission={mission} color={color} request={request} />
</div>
))}
</div>
</div>
<div className="w-full">
<div className="relative flex items-center gap-4">
<button
onClick={prevPage}
disabled={currentSlide === 0}
className="p-2 h-12 w-12 rounded-full hidden xl:flex items-center justify-center flex-shrink-0"
style={{
backgroundColor: currentSlide === 0 ? "#e5e5e5" : color,
color: currentSlide === 0 ? "#929292" : "white",
}}
aria-label="Diapositive précédente"
>
<RiArrowLeftLine />
</button>

<button
onClick={prevPage}
disabled={currentSlide === 0}
className="p-2 rounded-full absolute top-1/2 -translate-y-1/2 -left-10 hidden lg:flex"
style={{
backgroundColor: currentSlide === 0 ? "#e5e5e5" : color,
color: currentSlide === 0 ? "#929292" : "white",
}}
aria-label="Diapositive précédente"
>
<RiArrowLeftLine />
</button>
<div className="overflow-hidden md:max-w-[1056px] py-4 mx-auto">
<div className="flex transition-transform duration-500 ease-in-out" style={{ margin: "0 -0.75rem", transform: `translateX(-${currentSlide * (100 / slidesToShow)}%)` }}>
{missions.slice(0, 60).map((mission, i) => (
<div
role="group"
key={i}
id={mission._id}
aria-labelledby={mission._id}
className={`flex-shrink-0 ${missions.length <= 2 ? "w-full lg:w-auto sm:w-1/2 flex-shrink-0" : "w-full sm:w-1/2 lg:w-1/3"} px-3`}
>
<Card widget={widget} mission={mission} color={color} request={request} />
</div>
))}
</div>
</div>

<button
onClick={nextPage}
disabled={currentSlide >= missions.length - slidesToShow}
className="p-2 rounded-full absolute top-1/2 -translate-y-1/2 -right-10 hidden lg:flex"
style={{
backgroundColor: currentSlide >= missions.length - slidesToShow ? "#e5e5e5" : color,
color: currentSlide >= missions.length - slidesToShow ? "#929292" : "white",
}}
aria-label="Diapositive suivante"
>
<RiArrowRightLine />
</button>
<button
onClick={nextPage}
disabled={currentSlide >= missions.length - slidesToShow}
className="p-2 h-12 w-12 rounded-full hidden xl:flex items-center justify-center flex-shrink-0"
style={{
backgroundColor: currentSlide >= missions.length - slidesToShow ? "#e5e5e5" : color,
color: currentSlide >= missions.length - slidesToShow ? "#929292" : "white",
}}
aria-label="Diapositive suivante"
>
<RiArrowRightLine />
</button>
</div>

<div className="flex flex-col items-center mt-4 lg:hidden">
<div className="flex justify-center items-center gap-4 mb-2">
<div className="flex justify-center mt-4 xl:hidden">
<div className="flex gap-4">
<button
onClick={prevPage}
disabled={currentSlide === 0}
className="p-2 rounded-full flex items-center justify-center"
className="p-2 h-12 w-12 rounded-full flex items-center justify-center"
style={{
backgroundColor: currentSlide === 0 ? "#e5e5e5" : color,
color: currentSlide === 0 ? "#929292" : "white",
Expand All @@ -93,14 +101,10 @@ export const Carousel = ({ widget, missions, color, request }) => {
<RiArrowLeftLine size={20} />
</button>

<span className="text-sm text-gray-500">
{Math.floor(currentSlide / slidesToShow) + 1} / {Math.ceil(missions.length / slidesToShow)}
</span>

<button
onClick={nextPage}
disabled={currentSlide >= missions.length - slidesToShow}
className="p-2 rounded-full flex items-center justify-center"
className="p-2 h-12 w-12 rounded-full flex items-center justify-center"
style={{
backgroundColor: currentSlide >= missions.length - slidesToShow ? "#e5e5e5" : color,
color: currentSlide >= missions.length - slidesToShow ? "#929292" : "white",
Expand All @@ -111,6 +115,6 @@ export const Carousel = ({ widget, missions, color, request }) => {
</button>
</div>
</div>
</main>
</div>
);
};
Loading

0 comments on commit c81ff89

Please sign in to comment.