feat: add CSV export button in panel for contact database
All checks were successful
Deploy Production / Deploy to Production (push) Successful in 21s

- Plugin csv-export: authenticated route /wg-export/contacts generates
  CSV with UTF-8 BOM, semicolon separator, white-paper titles resolved
- Panel section with k-button wired to the route, index.css for spacing
- white-papers.yml dataTab converted to sections to host the custom section
- Filename format: YYMMDD-contacts.csv

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-06-01 14:00:23 +02:00
parent fb29a8fb98
commit effe6ec547
4 changed files with 130 additions and 54 deletions

View file

@ -48,62 +48,68 @@ tabs:
dataTab: dataTab:
label: Contacts label: Contacts
icon: chart icon: chart
fields: sections:
contactDatabase: export:
label: Ont téléchargé un livre blanc type: csv-export
type: structure contacts:
translate: false type: fields
columns:
firstName:
label: Prénom
width: 1/4
lastName:
label: Nom
width: 1/4
email:
label: Email
width: 1/4
company:
label: Entreprise
width: 1/4
role:
label: Fonction
whitePaper:
label: Livres blancs
downloadedAt:
label: Date
fields: fields:
firstName: contactDatabase:
label: Prénom label: Ont téléchargé un livre blanc
type: text type: structure
translate: false translate: false
required: true columns:
lastName: firstName:
label: Nom label: Prénom
type: text width: 1/5
translate: false lastName:
required: true label: Nom
company: width: 1/5
label: Société email:
type: text label: Email
translate: false width: 1/5
role: company:
label: Fonction label: Entreprise
type: text width: 1/5
translate: false role:
email: label: Fonction
type: email width: 1/5
translate: false whitePaper:
required: true label: Livres blancs
whitePaper: downloadedAt:
label: Livres blancs label: Date
type: pages fields:
translate: false firstName:
query: site.find('livres-blancs').children label: Prénom
downloadedAt: type: text
type: text translate: false
translate: false required: true
label: Date lastName:
label: Nom
type: text
translate: false
required: true
company:
label: Société
type: text
translate: false
role:
label: Fonction
type: text
translate: false
email:
type: email
translate: false
required: true
whitePaper:
label: Livres blancs
type: pages
translate: false
query: site.find('livres-blancs').children
downloadedAt:
type: text
translate: false
label: Date
files: tabs/files files: tabs/files
seo: seo/page seo: seo/page

View file

@ -0,0 +1,3 @@
.csv-export-btn {
margin-bottom: 2rem;
}

View file

@ -0,0 +1,17 @@
panel.plugin("world-game/csv-export", {
sections: {
"csv-export": {
template: `
<k-button
icon="download"
text="Exporter en CSV"
variant="filled"
theme="positive"
link="/wg-export/contacts"
target="_blank"
class="csv-export-btn"
/>
`,
},
},
});

View file

@ -0,0 +1,50 @@
<?php
Kirby::plugin('world-game/csv-export', [
'sections' => [
'csv-export' => [],
],
'routes' => [
[
'pattern' => 'wg-export/contacts',
'method' => 'GET',
'action' => function () {
if (!kirby()->user()) {
http_response_code(403);
exit;
}
$entries = page('livres-blancs')->contactDatabase()->toStructure();
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . date('ymd') . '-contacts.csv"');
header('Cache-Control: no-cache');
$out = fopen('php://output', 'w');
fputs($out, "\xEF\xBB\xBF"); // BOM pour Excel
fputcsv($out, ['Prénom', 'Nom', 'Email', 'Entreprise', 'Fonction', 'Livres blancs', 'Date'], ';');
foreach ($entries as $entry) {
$titles = [];
foreach ($entry->whitePaper()->toPages() as $wp) {
$titles[] = $wp->title()->value();
}
fputcsv($out, [
$entry->firstName()->value(),
$entry->lastName()->value(),
$entry->email()->value(),
$entry->company()->value(),
$entry->role()->value(),
implode(' | ', $titles),
$entry->downloadedAt()->value(),
], ';');
}
fclose($out);
exit;
},
],
],
]);