Skip to content

Commit

Permalink
feat: add bal widget config page
Browse files Browse the repository at this point in the history
  • Loading branch information
MaGOs92 committed Dec 8, 2023
1 parent 5809b07 commit dd90b9b
Show file tree
Hide file tree
Showing 12 changed files with 616 additions and 54 deletions.
176 changes: 176 additions & 0 deletions components/bal-widget/bal-widget-config-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/* eslint-disable @typescript-eslint/naming-convention */
import React, { useState, useMemo } from "react";
import styled from "styled-components";
import { Input } from "@codegouvfr/react-dsfr/Input";
import { Button } from "@codegouvfr/react-dsfr/Button";
import { Checkbox } from "@codegouvfr/react-dsfr/Checkbox";

import { BALWidgetConfig } from "../../types/bal-widget";
import { MultiStringInput } from "../multi-string-input";
import { MultiLinkInput } from "../multi-link-input";

type BALWidgetConfigFormProps = {
config: BALWidgetConfig;
onSubmit: (data: BALWidgetConfig) => Promise<void>;
};

const StyledForm = styled.form`
h3,
h4 {
margin-bottom: 1rem;
}
section {
margin: 1rem 0;
}
.form-controls {
display: flex;
align-items: center;
> :not(:first-child) {
margin-left: 1rem;
}
}
`;

const defaultConfig: BALWidgetConfig = {
global: {
title: "Centre d'aide Base Adresse Locale",
hideWidget: false,
showOnPages: [],
},
gitbook: {
welcomeBlockTitle: "Ces articles pourraient vous aider",
topArticles: [],
},
contactUs: {
welcomeBlockTitle: "Nous contacter",
subjects: [],
},
};

export const BALWidgetConfigForm = ({
onSubmit,
config: baseConfig,
}: BALWidgetConfigFormProps) => {
const initialConfig = baseConfig ? { ...baseConfig } : { ...defaultConfig };
const [formData, setFormData] = useState<BALWidgetConfig>(initialConfig);

const canPublish = useMemo(() => {
return JSON.stringify(formData) !== JSON.stringify(initialConfig);
}, [formData, initialConfig]);

const handleEdit =
(section: keyof BALWidgetConfig, property: string) =>
(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { value } = e.target;
setFormData((state) => ({
...state,
[section]: {
...state[section],
[property]: value,
},
}));
};

const handleToggle =
(section: keyof BALWidgetConfig, property: string) => () => {
setFormData((state) => ({
...state,
[section]: {
...state[section],
[property]: !state[section][property],
},
}));
};

const resetForm = () => {
setFormData(initialConfig);
};

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
await onSubmit(formData);
};

return (
<StyledForm onSubmit={handleSubmit} className="fr-my-4w">
<h3>Configuration du widget</h3>
<section>
<h4>Globale</h4>
<Input
label="Titre du widget"
nativeInputProps={{
required: true,
value: formData.global.title,
onChange: handleEdit("global", "title"),
}}
/>
<Checkbox
className="perimeter-checkbox"
options={[
{
label: "Cacher le widget",
nativeInputProps: {
checked: formData.global.hideWidget,
onChange: handleToggle("global", "hideWidget"),
},
},
]}
/>
<MultiStringInput
label="Afficher le widget uniquement sur les pages :"
value={formData.global.showOnPages}
onChange={(value) =>
handleEdit("global", "showOnPages")({ target: { value } } as any)
}
/>
</section>
<section>
<h4>Gitbook</h4>
<Input
label="Titre sur la page d'accueil"
nativeInputProps={{
required: true,
value: formData.gitbook.welcomeBlockTitle,
onChange: handleEdit("gitbook", "welcomeBlockTitle"),
}}
/>
<MultiLinkInput
label="Articles populaires :"
value={formData.gitbook.topArticles}
onChange={(value) =>
handleEdit("gitbook", "topArticles")({ target: { value } } as any)
}
/>
</section>
<section>
<h4>Formulaire de contact</h4>
<Input
label="Titre sur la page d'accueil"
nativeInputProps={{
required: true,
value: formData.contactUs.welcomeBlockTitle,
onChange: handleEdit("contactUs", "welcomeBlockTitle"),
}}
/>
<MultiStringInput
label="Sujets du formulaire de contact :"
value={formData.contactUs.subjects}
onChange={(value) =>
handleEdit("contactUs", "subjects")({ target: { value } } as any)
}
/>
</section>
<div className="form-controls">
<Button disabled={!canPublish} type="submit" iconId="fr-icon-save-line">
Publier
</Button>
<Button disabled={!canPublish} type="button" onClick={resetForm}>
Annuler
</Button>
</div>
</StyledForm>
);
};
162 changes: 108 additions & 54 deletions components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,149 @@
import Link from 'next/link'
import {signIn, signOut} from 'next-auth/react'
import type {Session} from 'next-auth'
import React from "react";
import Link from "next/link";
import { signIn, signOut } from "next-auth/react";
import type { Session } from "next-auth";

type HeaderProps = {
session: Session;
}
};

const Header = ({session}: HeaderProps) => (
<header role='banner' className='fr-header'>
<div className='fr-header__body'>
<div className='fr-container'>
<div className='fr-header__body-row'>
<div className='fr-header__brand fr-enlarge-link'>
<div className='fr-header__brand-top'>
<Link href='/'>
<div className='fr-header__logo'>
<p className='fr-logo'>
const Header = ({ session }: HeaderProps) => (
<header role="banner" className="fr-header">
<div className="fr-header__body">
<div className="fr-container">
<div className="fr-header__body-row">
<div className="fr-header__brand fr-enlarge-link">
<div className="fr-header__brand-top">
<Link href="/">
<div className="fr-header__logo">
<p className="fr-logo">
Base Adresse Locale <br />
Admin
</p>
</div>
</Link>
<div className='fr-header__navbar'>
<button className='fr-btn--menu fr-btn' type='button' data-fr-opened='false' aria-controls='modal-499' aria-haspopup='menu' id='button-500' title='Menu'>
<div className="fr-header__navbar">
<button
className="fr-btn--menu fr-btn"
type="button"
data-fr-opened="false"
aria-controls="modal-499"
aria-haspopup="menu"
id="button-500"
title="Menu"
>
Menu
</button>
</div>
</div>
<div className='fr-header__service'>
<Link href='/' title='Accueil - [BAL Admin / ANCT]'>
<p className='fr-header__service-title'>
<div className="fr-header__service">
<Link href="/" title="Accueil - [BAL Admin / ANCT]">
<p className="fr-header__service-title">
Base Adresse Locale / Admin - ANCT
</p>
</Link>
<p className='fr-header__service-tagline'>Interface d’administration des services Base Adresse Locale</p>
<p className="fr-header__service-tagline">
Interface d’administration des services Base Adresse Locale
</p>
</div>
</div>
<div className='fr-header__tools'>
<div className='fr-header__tools-links'>
<ul className='fr-btns-group'>
<li style={{alignItems: 'center'}}>
{session ? (<>
<div style={{marginRight: 10}}>{session?.user?.name}</div>
<button onClick={async () => signOut()} type='button' style={{margin: 0}} className='fr-btn fr-icon-logout-box-r-line' >
Déconnexion
</button>
</>
)
: <button onClick={async () => signIn()} type='button' style={{margin: 0}} className='fr-btn fr-icon-logout-box-r-line' >
<div className="fr-header__tools">
<div className="fr-header__tools-links">
<ul className="fr-btns-group">
<li style={{ alignItems: "center" }}>
{session ? (
<>
<div style={{ marginRight: 10 }}>
{session?.user?.name}
</div>
<button
onClick={async () => signOut()}
type="button"
style={{ margin: 0 }}
className="fr-btn fr-icon-logout-box-r-line"
>
Déconnexion
</button>
</>
) : (
<button
onClick={async () => signIn()}
type="button"
style={{ margin: 0 }}
className="fr-btn fr-icon-logout-box-r-line"
>
Connexion
</button>}
</button>
)}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div className='fr-header__menu fr-modal' id='modal-499' aria-labelledby='button-500'>
<div className='fr-container'>
<button className='fr-btn--close fr-btn' type='button' aria-controls='modal-499' title='Fermer'>
<div
className="fr-header__menu fr-modal"
id="modal-499"
aria-labelledby="button-500"
>
<div className="fr-container">
<button
className="fr-btn--close fr-btn"
type="button"
aria-controls="modal-499"
title="Fermer"
>
Fermer
</button>
<div className='fr-header__menu-links' />
<nav className='fr-nav' id='navigation-494' role='navigation' aria-label='Menu principal'>
<ul className='fr-nav__list'>
<li className='fr-nav__item'>
<Link href='/communes'>
<a className='fr-nav__link' target='_self'>Communes</a>
<div className="fr-header__menu-links" />
<nav
className="fr-nav"
id="navigation-494"
role="navigation"
aria-label="Menu principal"
>
<ul className="fr-nav__list">
<li className="fr-nav__item">
<Link href="/communes">
<a className="fr-nav__link" target="_self">
Communes
</a>
</Link>
</li> <li className='fr-nav__item'>
<Link href='/api-depot'>
<a className='fr-nav__link' target='_self'>API Dépôt</a>
</li>{" "}
<li className="fr-nav__item">
<Link href="/api-depot">
<a className="fr-nav__link" target="_self">
API Dépôt
</a>
</Link>
</li>
<li className='fr-nav__item'>
<Link href='/moissonneur-bal'>
<a className='fr-nav__link' target='_self'>Moissonneur BAL</a>
<li className="fr-nav__item">
<Link href="/moissonneur-bal">
<a className="fr-nav__link" target="_self">
Moissonneur BAL
</a>
</Link>
</li>
<li className='fr-nav__item'>
<Link href='/partenaires-de-la-charte'>
<a className='fr-nav__link' target='_self'>Partenaires de la charte</a>
<li className="fr-nav__item">
<Link href="/partenaires-de-la-charte">
<a className="fr-nav__link" target="_self">
Partenaires de la charte
</a>
</Link>
</li>
<li className="fr-nav__item">
<Link href="/bal-widget">
<a className="fr-nav__link" target="_self">
BAL Widget
</a>
</Link>
</li>

</ul>
</nav>
</div>
</div>
</header>
)
);

export default Header
export default Header;
Loading

0 comments on commit dd90b9b

Please sign in to comment.