From 58f76f7a4a1aff7b94c9f45da655b1dba1bca7e9 Mon Sep 17 00:00:00 2001 From: MelFonk Date: Fri, 13 Dec 2024 16:15:07 +0100 Subject: [PATCH] Portage page geocoder CSV nouveau design --- .../csv/components/action-button-neutral.tsx | 42 ++++----- .../csv/components/columns-select.style.tsx | 46 ++++++++++ .../outils/csv/components/columns-select.tsx | 44 +--------- src/app/outils/csv/components/filter.tsx | 31 ------- src/app/outils/csv/components/geocoder.tsx | 19 +---- .../outils/csv/components/holder.styles.tsx | 80 ----------------- src/app/outils/csv/components/holder.tsx | 72 ---------------- .../components/selectable-item-list.style.tsx | 47 ++++++++++ .../csv/components/selectable-item-list.tsx | 47 +--------- src/app/outils/csv/components/step.tsx | 8 -- src/app/outils/csv/components/table.tsx | 42 --------- src/app/outils/csv/page.styles.tsx | 26 ++++++ src/app/outils/csv/page.tsx | 85 +++++++++---------- 13 files changed, 187 insertions(+), 402 deletions(-) create mode 100644 src/app/outils/csv/components/columns-select.style.tsx delete mode 100644 src/app/outils/csv/components/filter.tsx delete mode 100644 src/app/outils/csv/components/holder.styles.tsx delete mode 100644 src/app/outils/csv/components/holder.tsx create mode 100644 src/app/outils/csv/components/selectable-item-list.style.tsx delete mode 100644 src/app/outils/csv/components/table.tsx diff --git a/src/app/outils/csv/components/action-button-neutral.tsx b/src/app/outils/csv/components/action-button-neutral.tsx index 744d1a518..5d57ff75c 100644 --- a/src/app/outils/csv/components/action-button-neutral.tsx +++ b/src/app/outils/csv/components/action-button-neutral.tsx @@ -1,36 +1,38 @@ -import colors from '@/theme' -import Button from '@codegouvfr/react-dsfr/Button' +'use client' -interface ActionButtonNeutralPropTypes { - children: React.ReactNode - label: string - isFullSize: boolean - [key: string]: any -} +import Button from '@codegouvfr/react-dsfr/Button' +import styled from 'styled-components' -export default function ActionButtonNeutral({ children, label, isFullSize = false, ...props }: ActionButtonNeutralPropTypes) { - return ( - + ` +interface ActionButtonNeutralPropTypes { + children: React.ReactNode + label: string + isFullSize: boolean + [key: string]: any +} + +export default function ActionButtonNeutral({ children, label, isFullSize = false, ...props }: ActionButtonNeutralPropTypes) { + return ( + + + ) } diff --git a/src/app/outils/csv/components/columns-select.style.tsx b/src/app/outils/csv/components/columns-select.style.tsx new file mode 100644 index 000000000..1a4efad8f --- /dev/null +++ b/src/app/outils/csv/components/columns-select.style.tsx @@ -0,0 +1,46 @@ +'use client' + +import styled from 'styled-components' +import theme from '@/theme' + +export const ColumnSelectWrapper = styled.div` + .columns { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(auto, 200px)); + grid-gap: 5px; + } + + .item { + display: flex; + align-items: center; + justify-content: space-between; + border: 1px solid ${theme.colors.grey.border}; + } + + .item .text { + background-color: ${theme.colors.primary}; + } + + .item:hover { + cursor: pointer; + } + + .column { + margin: 0 1em; + } + + .selection { + margin: 2em 0; + padding: 0.5em; + border: 1px dashed #ccc; + } + + .button { + font-size: larger; + font-weight: bold; + text-align: center; + width: 20px; + color: ${theme.colors.grey}; + background-color: ${theme.colors.grey.badge}; + } + ` diff --git a/src/app/outils/csv/components/columns-select.tsx b/src/app/outils/csv/components/columns-select.tsx index a47b067c5..befe1bbeb 100644 --- a/src/app/outils/csv/components/columns-select.tsx +++ b/src/app/outils/csv/components/columns-select.tsx @@ -1,5 +1,5 @@ import SelectableItemList from '../components/selectable-item-list' -import theme from '@/theme/theme' +import { ColumnSelectWrapper } from './columns-select.style' interface ColumnsSelectPropTypes { columns: Array @@ -10,7 +10,7 @@ interface ColumnsSelectPropTypes { export default function ColumnsSelect({ columns, selectedColumns, onAdd, onRemove }: ColumnsSelectPropTypes) { return ( -
+ !selectedColumns.includes(col)).map((col) => { return { @@ -34,44 +34,6 @@ export default function ColumnsSelect({ columns, selectedColumns, onAdd, onRemov buttonIcon="-" action={onRemove} /> - -
+ ) } diff --git a/src/app/outils/csv/components/filter.tsx b/src/app/outils/csv/components/filter.tsx deleted file mode 100644 index cf34a7301..000000000 --- a/src/app/outils/csv/components/filter.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react' - -interface FilterPropTypes { - selected: string - columns: string[] - onSelect: Function -} - -export default function Filter({ selected = '', columns, onSelect }: FilterPropTypes) { - return ( -
-
- -
- -
- ) -} diff --git a/src/app/outils/csv/components/geocoder.tsx b/src/app/outils/csv/components/geocoder.tsx index 66f760b15..1f6e3f642 100644 --- a/src/app/outils/csv/components/geocoder.tsx +++ b/src/app/outils/csv/components/geocoder.tsx @@ -45,7 +45,7 @@ export default function Geocoder({ file, columns, filter }: GeocodeurPropTypes) } } return ( -
+
{!status && ( )} @@ -68,23 +68,6 @@ export default function Geocoder({ file, columns, filter }: GeocodeurPropTypes) {error && (

{error.message}
Code erreur : {error.name}

)} - -
) } diff --git a/src/app/outils/csv/components/holder.styles.tsx b/src/app/outils/csv/components/holder.styles.tsx deleted file mode 100644 index 55e826bb0..000000000 --- a/src/app/outils/csv/components/holder.styles.tsx +++ /dev/null @@ -1,80 +0,0 @@ -'use client' - -import styled from 'styled-components' -import theme from '@/theme' - -export const HolderWrapper = styled.div` - - .dropzone { - display: flex; - flex-flow: column; - justify-content: center; - width: 100%; - border: 1px dashed #ccc; - height: 200px; - text-align: center; - cursor: pointer; - border-radius: 4px; - } - - .dropzone:hover { - background-color: #ebeff3; - } - - .dropzone.file { - display: flex; - flex-flow: column; - height: auto; - border: none; - } - - .file-container { - width: 100%; - } - - .file-sumup { - display: flex; - align-items: center; - justify-content: space-between; - text-align: left; - } - - .file-details { - display: flex; - align-items: center; - } - - .file-infos { - border-left: 3px solid ${theme.colors.primary.border}; - margin-left: 5px; - padding: 0 5px; - } - - .name { - font-weight: bolder; - } - - .size { - font-style: italic; - font-size: 14px; - } - - .active { - background-color: #ebeff3; - } - - .loading { - display: flex; - align-items: center; - justify-content: space-between; - font-style: italic; - } - .loading span { - margin-left: 1em; - } - - span > .fr-icon-refresh-fill { - margin-right: 10px; - color: var(--blue-france-sun-113-625); - } - ` diff --git a/src/app/outils/csv/components/holder.tsx b/src/app/outils/csv/components/holder.tsx deleted file mode 100644 index 5998de5e5..000000000 --- a/src/app/outils/csv/components/holder.tsx +++ /dev/null @@ -1,72 +0,0 @@ -'use client' - -import { useState } from 'react' -import Dropzone from 'react-dropzone' - -import Loader from '@/components/Loader/index' -import { HolderWrapper } from './holder.styles' - -function formatFileSize(bytes: number) { - if (bytes === 0) { - return '0 Bytes' - } - - const k = 1000 - const sizes = ['Bytes', 'KB', 'MB'] - const i = Math.floor(Math.log(bytes) / Math.log(k)) - return Number.parseFloat((bytes / (k ** i)).toFixed(2)) + ' ' + sizes[i] -} - -interface HolderParameters { - file: File | null - placeholder: string - isLoading: boolean - onDrop: (FileList: File[]) => void -} - -export default function Holder({ file = null, placeholder, isLoading = false, onDrop }: HolderParameters) { - const [isHovered, setIsHovered] = useState(false) - - return ( - - {({ getRootProps, getInputProps, isDragActive }) => { - const rootProps = getRootProps() - const inputProps = getInputProps() - - return ( - -
setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - > - -
{!file &&

Glisser le fichier

}
-
{file - ? ( -
-
-
-
{file.name}
-
{formatFileSize(file.size)}
-
-
- {isLoading - ? ( -
Chargement du fichier…
- ) - : ( -
- ) - : placeholder} -
-
-
- ) - }} -
- ) -} diff --git a/src/app/outils/csv/components/selectable-item-list.style.tsx b/src/app/outils/csv/components/selectable-item-list.style.tsx new file mode 100644 index 000000000..adcc4d6c1 --- /dev/null +++ b/src/app/outils/csv/components/selectable-item-list.style.tsx @@ -0,0 +1,47 @@ +'use client' + +import styled from 'styled-components' +import theme from '@/theme' + +export const SelectableItemListWrapper = styled.div` + .list { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(auto, 200px)); + grid-gap: 5px; + } + + .item { + display: flex; + align-items: center; + justify-content: space-between; + border: 1px solid ${theme.colors.grey.main}; + white-space: nowrap; + width: 100%; + background: ${theme.colors.primary.bg}; + color: ${theme.colors.grey.main}; + cursor: pointer; + } + + .item .text { + overflow: auto; + text-overflow: ellipsis; + margin-left: 0.5em; + margin-right: 0.5em; + color: ${theme.colors.grey}; + } + + .selection { + margin: 2em 0; + padding: 0.5em; + border: 1px dashed #ccc; + background: #fff; + } + + .button { + font-size: larger; + font-weight: bold; + text-align: center; + min-width: 20px; + background: ${theme.colors.primary.badge}; + } +` diff --git a/src/app/outils/csv/components/selectable-item-list.tsx b/src/app/outils/csv/components/selectable-item-list.tsx index c922a2fab..2a3d07138 100644 --- a/src/app/outils/csv/components/selectable-item-list.tsx +++ b/src/app/outils/csv/components/selectable-item-list.tsx @@ -1,6 +1,6 @@ import React from 'react' -import theme from '@/theme/theme' +import { SelectableItemListWrapper } from './selectable-item-list.style' import ActionButtonNeutral from '../components/action-button-neutral' @@ -12,7 +12,7 @@ interface SelectableItemListPropType { export default function SelectableItemList({ list, buttonIcon, action }: SelectableItemListPropType) { return ( -
+
0 && 'list selection'}`}> {list.map(item => typeof (item.value) === 'string' && ( ))}
- -
+ ) } diff --git a/src/app/outils/csv/components/step.tsx b/src/app/outils/csv/components/step.tsx index ea88347c7..1b9f4eb40 100644 --- a/src/app/outils/csv/components/step.tsx +++ b/src/app/outils/csv/components/step.tsx @@ -1,5 +1,3 @@ -import theme from '@/theme/theme' - interface StepPropTypes { title: string children: React.ReactNode @@ -11,12 +9,6 @@ function Step({ title, children = null }: StepPropTypes) {

{title}

{children} -
) } diff --git a/src/app/outils/csv/components/table.tsx b/src/app/outils/csv/components/table.tsx deleted file mode 100644 index 8db34be82..000000000 --- a/src/app/outils/csv/components/table.tsx +++ /dev/null @@ -1,42 +0,0 @@ -interface PropTypesTable { - headers: Array - rows: Array - -} - -export default function Table({ headers, rows }: PropTypesTable) { - return ( - - - - {headers.map(header => )} - - {rows.map((row, idx) => ( - - {row.map((item, index) => )} - - ))} - - -
{header}
{item}
- ) -} diff --git a/src/app/outils/csv/page.styles.tsx b/src/app/outils/csv/page.styles.tsx index a40404a6d..66f80cba4 100644 --- a/src/app/outils/csv/page.styles.tsx +++ b/src/app/outils/csv/page.styles.tsx @@ -1,6 +1,7 @@ 'use client' import styled from 'styled-components' +import theme from '@/theme' export const TextWrapper = styled.div` @@ -18,4 +19,29 @@ export const TextWrapper = styled.div` .error { color: red; } + + .col { + display: flex; + align-items: center; + } + + .file-details { + display: flex; + align-items: center; + } + + .file-infos { + border-left: 3px solid ${theme.colors.primary.border}; + margin-left: 5px; + padding: 0 5px; + } + + .disabled { + color: ${theme.colors.grey.badge}; + } + + .fr-table { + display: block; + overflow: scroll; + } ` diff --git a/src/app/outils/csv/page.tsx b/src/app/outils/csv/page.tsx index 21d8e8f8d..9384e0da9 100644 --- a/src/app/outils/csv/page.tsx +++ b/src/app/outils/csv/page.tsx @@ -3,18 +3,15 @@ import React, { useState } from 'react' import Papa from 'papaparse' import detectEncoding from '@/lib/detect-encoding' - import Section from '@/components/Section/Section' -import Button from '@codegouvfr/react-dsfr/Button' -import Breadcrumb from '@codegouvfr/react-dsfr/Breadcrumb' -import Step from './components/step' -import ColumnsSelect from './components/columns-select' -import Filter from './components/filter' -import Holder from './components/holder' -import Table from './components/table' import Geocoder from './components/geocoder' -import Loader from '@/components/Loader/index' import { TextWrapper } from './page.styles' +import Accordion from '@codegouvfr/react-dsfr/Accordion' +import Select from '@codegouvfr/react-dsfr/Select' +import Step from './components/step' +import ColumnsSelect from './components/columns-select' +import DropZoneInput from '@/components/DropZoneInput' +import Table from '@codegouvfr/react-dsfr/Table' const allowedTypes = new Set([ 'text/plain', @@ -86,8 +83,10 @@ export default function Csv() { } } - const handleFileDrop = (fileList: File[]) => { - const file = fileList[0] + const handleFileDrop = (file?: File) => { + if (!file) { + throw new Error('No file selected') + } const fileExtension = getFileExtension(file.name) if (file.type && !allowedTypes.has(file.type)) { setError(Error(`Ce type de fichier n’est pas supporté : ${file.type}.`)) @@ -132,36 +131,28 @@ export default function Csv() { } const columns = csv ? csv.data[0] : [] + return ( <> - {/* */}

1. Choisir un fichier

- - - - {loading && ( -
-

Analyse du fichier en cours…

- + + + {file + && ( +
+
+
Nom du fichier : {file.name}
+
Taille : {((file.size / 10 ** 6) <= 1) ? (file.size) + ' octets' : (file.size / 10 ** 6) + ' Mo'}
+
)} @@ -171,7 +162,7 @@ export default function Csv() {
- {csv && } + {csv &&
} @@ -189,17 +180,19 @@ export default function Csv() { {csv && ( <>
- - - {advancedPanel && ( - - )} + + {advancedPanel && ( + + )} +
{file && (