-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
616 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.