-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
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"; | ||
Check failure on line 2 in components/bal-widget/bal-widget-config-form.tsx GitHub Actions / build (18.x)
Check failure on line 2 in components/bal-widget/bal-widget-config-form.tsx GitHub Actions / build (18.x)
Check failure on line 2 in components/bal-widget/bal-widget-config-form.tsx GitHub Actions / build (18.x)
|
||
import styled from "styled-components"; | ||
Check failure on line 3 in components/bal-widget/bal-widget-config-form.tsx GitHub Actions / build (18.x)
|
||
import { Input } from "@codegouvfr/react-dsfr/Input"; | ||
Check failure on line 4 in components/bal-widget/bal-widget-config-form.tsx GitHub Actions / build (18.x)
Check failure on line 4 in components/bal-widget/bal-widget-config-form.tsx GitHub Actions / build (18.x)
Check failure on line 4 in components/bal-widget/bal-widget-config-form.tsx GitHub Actions / build (18.x)
|
||
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> | ||
); | ||
}; |
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; |