Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List attributes in database page #215

Merged
merged 2 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 11 additions & 31 deletions app/(normalLayout)/outils-services/rapprochement/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import { getDatabases } from '@/utils/databases';

// Comps
import DBCard from '@/components/DBCard';
import ImageNext from 'next/image';
import { Card } from '@codegouvfr/react-dsfr/Card';
import SearchableDatabaseSection from '@/components/SearchableDatabaseSection';
import PivotIllustration from '@/components/PivotIllustration';

// Settings
import settings from '@/logic/settings';
Expand All @@ -21,7 +21,12 @@ import bdgRiverPhoto from '@/public/images/bdg-river.jpg';
import siloPhoto from '@/public/images/silo-bdg.jpg';

export default async function Page() {
const dbs = await getDatabases();
let dbs = null;
try {
dbs = await getDatabases();
} catch (error) {
console.error('Error fetching databases:', error);
}

return (
<>
Expand Down Expand Up @@ -59,23 +64,11 @@ export default async function Page() {
</div>
</div>

{dbs && <SearchableDatabaseSection databases={dbs} />}

<div className="section">
<div className="fr-grid-row ">
<div className="fr-col-12 fr-col-md-8 fr-col-offset-md-2">
<div className="section__titleblock">
<h2 id="liste" className="section__title">
Les bases contenant des identifiants RNB
</h2>
<p className="section__subtitle">
Performance énergétique, insalubrité, équipements sportifs,
copropriétés, ...
</p>
</div>

{dbs.map((db: any) => {
return <DBCard key={db.key} db={db} />;
})}

<p>
Votre base contient des identifiants RNB et vous souhaitez en
faire la promotion sur cette page ?<br />
Expand Down Expand Up @@ -105,20 +98,7 @@ export default async function Page() {
données jusqu&apos;à présent isolées.
</h3>
<div className={styles.pivotBlockSentence}>
<div className="none md-block">
<ImageNext
className="resp-image"
src={pivotIllu}
alt="Illustration d’un pivot"
/>
</div>
<div className="md-none">
<ImageNext
className="resp-image"
src={pivotIlluMobile}
alt="Illustration d’un pivot"
/>
</div>
<PivotIllustration />
</div>
</div>
</div>
Expand Down
24 changes: 17 additions & 7 deletions app/(normalLayout)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import ImageNext from 'next/image';
import CasListe from '@/components/CasListe';
import NewsletterForm from '@/components/NewsletterForm';
import AddressSearchHome from '@/components/AddressSearchHome';
import DatabaseSearchForm from '@/components/DatabaseSearchForm';
import PivotIllustration from '@/components/PivotIllustration';

// Banner
import bannerPic from '@/public/images/homeBanner/bordeaux.jpg';
Expand All @@ -31,16 +33,19 @@ import adsIllu from '@/public/images/ads.png';
import { getBreakingNews } from '@/utils/blog';

// Utils
import { getDatabasesCount, getFeaturedDatabases } from '@/utils/databases';
import HomeDBList from '@/components/homeDBList';
import { getDatabases } from '@/utils/databases';

export const revalidate = 10;

export default async function Home() {
const bannerId = 'M11Z4KK9Y338';
const breakingNews = await getBreakingNews();
const dbs = await getFeaturedDatabases();
const dbsCount = await getDatabasesCount();
let availableDatabases = null;
try {
availableDatabases = await getDatabases();
} catch (error) {
console.error('Error fetching databases:', error);
}

return (
<>
Expand Down Expand Up @@ -139,18 +144,23 @@ export default async function Home() {
</div>
</div>

<div className="section section__big ">
<div className="section section__big">
<div className={styles.dbsShell}>
<div className="section__titleblock">
<h2 className="section__title">
Enrichissez vos bases de données bâtimentaires
Croisez et enrichissez vos données bâtimentaires
</h2>
<p className="section__subtitle">
Les identifiants de bâtiments RNB servent de pivot entre des
données jusqu&apos;à présent isolées
</p>
</div>
<HomeDBList dbs={dbs} dbsCount={dbsCount} />
{availableDatabases && (
<div className={styles.searchContainer}>
<DatabaseSearchForm dbs={availableDatabases} />
</div>
)}
{!availableDatabases && <PivotIllustration />}
</div>
</div>

Expand Down
44 changes: 33 additions & 11 deletions components/DBCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,73 @@ import styles from '@/styles/dbcard.module.scss';
// Components
import ImageNext from 'next/image';
import Badge from '@codegouvfr/react-dsfr/Badge';
import Table from '@codegouvfr/react-dsfr/Table';

// Analytics
import va from '@vercel/analytics';
import { DiffusionDatabase, Attribute } from './diffusionDatabase.type';

export default function Entry({ db }) {
const imagePath = function (filaname: string) {
return `/images/databases/${filaname}`;
};
const AttributesTable = ({ attributes }: { attributes: Attribute[] }) => {
return (
<Table
className={styles.attributesTable}
data={attributes.map((attribute) => [
attribute.name,
attribute.description,
])}
hasHeader={false}
size={'sm'}
noCaption
/>
);
};

type Props = {
db: DiffusionDatabase;
attributes: Attribute[];
displayAttributes: boolean;
};

const trackDbClick = (db) => {
export default function Entry({ db, attributes, displayAttributes }: Props) {
const trackDbClick = (db: DiffusionDatabase) => {
return () => {
va.track('db-click-on-page', {
db_key: db.key,
db_name: db.name,
});
};
};

return (
<>
<div className={styles.card} id={db.key}>
<div className={styles.card}>
<div className={styles.logoShell}>
<ImageNext
className={styles.logo}
width="30"
height="30"
src={imagePath(db.image)}
src={db.image_url || ''}
alt={db.name}
placeholder="empty"
/>
</div>

<div className={styles.body}>
<div className={styles.titleBlock}>
<h3 className={styles.title}>
<a onClick={trackDbClick(db)} href={db.url}>
<a onClick={trackDbClick(db)} href={db.documentation_url}>
{db.name}
</a>
</h3>
<div className={styles.meta}>
<span>Editée par {db.published_by}</span>
<span>Editée par {db.publisher}</span>
<span>{db.licence}</span>
</div>
</div>

<p className={styles.description}>{db.description}</p>
{!displayAttributes && (
<p className={styles.description}>{db.description}</p>
)}
{displayAttributes && <AttributesTable attributes={attributes} />}

<div>
{db.tags.map((tag) => (
Expand Down
85 changes: 85 additions & 0 deletions components/DatabaseSearchForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
'use client';

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import SearchBar from '@codegouvfr/react-dsfr/SearchBar';
import styles from '@/styles/home.module.scss';
import { DiffusionDatabase } from './diffusionDatabase.type';
import ImageNext from 'next/image';
import Link from 'next/link';

function FeaturedDatabases({ dbs }: { dbs: DiffusionDatabase[] }) {
return (
<div className={styles.featuredDatabases}>
{dbs.map((db) => (
<div
className={styles.featuredDatabases__item}
title={db.featured_summary || ''}
key={db.id}
>
<ImageNext
src={db.image_url || ''}
alt={db.name}
width="52"
height="52"
className={styles.featuredDatabases__item__logo}
placeholder="empty"
/>
</div>
))}
</div>
);
}

export default function DatabaseSearchForm({
dbs,
}: {
dbs: DiffusionDatabase[];
}) {
const router = useRouter();
const [query, setQuery] = useState('');

const databaseCount = dbs.length;
const attributeCount = dbs.reduce((acc, db) => acc + db.attributes.length, 0);
const featuredDatabases = dbs.filter((db) => db.is_featured);

const handleSubmit = (text: string) => {
const search = text.trim();
if (search !== '') {
router.push(
`/outils-services/rapprochement?search=${encodeURIComponent(search)}`,
);
}
};

return (
<>
<div>
<b>
Recherchez parmi {attributeCount} attributs accessibles dans{' '}
{databaseCount} bases répertoriées
</b>
</div>
<SearchBar
label="Rechercher"
className={styles.searchBar}
big
onButtonClick={handleSubmit}
renderInput={({ className, id, type }) => (
<input
className={className}
placeholder="Rechercher parmi les attributs répertoriés"
id={id}
type={type}
value={query}
onChange={(e) => setQuery(e.currentTarget.value)}
/>
)}
/>
<FeaturedDatabases dbs={featuredDatabases} />
<Link href="/outils-services/rapprochement">
Voir l&apos;ensemble des bases contenant des ID-RNB
</Link>
</>
);
}
24 changes: 24 additions & 0 deletions components/PivotIllustration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import ImageNext from 'next/image';
import pivotIllu from '@/public/images/pivot-sentence.png';
import pivotIlluMobile from '@/public/images/pivot-sentence-mobile.png';

export default function PivotIllustration() {
return (
<>
<div className="none md-block">
<ImageNext
className="resp-image"
src={pivotIllu}
alt="Illustration d’un pivot"
/>
</div>
<div className="md-none">
<ImageNext
className="resp-image"
src={pivotIlluMobile}
alt="Illustration d’un pivot"
/>
</div>
</>
);
}
Loading