Update project dependencies and enhance documentation
- Added `barryvdh/laravel-dompdf` to `composer.json` for PDF generation capabilities. - Updated `boost.json` to include `tailwindcss-development` in skills. - Modified `package.json` and `package-lock.json` to upgrade Tailwind CSS and related packages. - Improved README.md for clarity and corrected French language errors. - Created design system documentation for Filament components. - Added new Filament pages for Dashboard and Documentation with dynamic content loading. - Enhanced TablesExplorer functionality with improved table and column management.
This commit is contained in:
191
resources/css/filament/admin/theme.css
Normal file
191
resources/css/filament/admin/theme.css
Normal file
@@ -0,0 +1,191 @@
|
||||
@import '../../../../vendor/filament/filament/resources/css/theme.css';
|
||||
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@source '../../../../app/Filament/**/*';
|
||||
@source '../../../../resources/views/filament/**/*';
|
||||
@source '../../../../resources/views/components/logistics/**/*';
|
||||
|
||||
/* --- Documentation prose overrides (dark mode Filament) --- */
|
||||
|
||||
.documentation-prose {
|
||||
--tw-prose-body: theme(--color-gray-300);
|
||||
--tw-prose-headings: theme(--color-white);
|
||||
--tw-prose-links: theme(--color-blue-400);
|
||||
--tw-prose-bold: theme(--color-white);
|
||||
--tw-prose-code: theme(--color-blue-300);
|
||||
--tw-prose-hr: theme(--color-white/10);
|
||||
--tw-prose-th-borders: theme(--color-white/10);
|
||||
--tw-prose-td-borders: theme(--color-white/5);
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.documentation-prose h1 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.025em;
|
||||
padding-bottom: 0.75rem;
|
||||
border-bottom: 1px solid oklch(from white l c h / 0.1);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.documentation-prose h2 {
|
||||
font-size: 1.35rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.015em;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid oklch(from white l c h / 0.07);
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.documentation-prose h3 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.documentation-prose h4 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: oklch(from white l c h / 0.85);
|
||||
}
|
||||
|
||||
.documentation-prose hr {
|
||||
border-color: oklch(from white l c h / 0.1);
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.documentation-prose a {
|
||||
color: oklch(0.7 0.15 250);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
|
||||
.documentation-prose a:hover {
|
||||
color: oklch(0.8 0.15 250);
|
||||
}
|
||||
|
||||
/* --- Tables --- */
|
||||
|
||||
.documentation-prose table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.8125rem;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border: 1px solid oklch(from white l c h / 0.1);
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.documentation-prose thead {
|
||||
background: oklch(from white l c h / 0.05);
|
||||
}
|
||||
|
||||
.documentation-prose thead tr {
|
||||
border-bottom: 1px solid oklch(from white l c h / 0.1);
|
||||
}
|
||||
|
||||
.documentation-prose th {
|
||||
padding: 0.625rem 0.75rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: oklch(from white l c h / 0.6);
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.documentation-prose td {
|
||||
padding: 0.5rem 0.75rem;
|
||||
color: oklch(from white l c h / 0.75);
|
||||
vertical-align: top;
|
||||
border-top: 1px solid oklch(from white l c h / 0.05);
|
||||
}
|
||||
|
||||
.documentation-prose tbody tr:hover {
|
||||
background: oklch(from white l c h / 0.03);
|
||||
}
|
||||
|
||||
/* --- Code blocks --- */
|
||||
|
||||
.documentation-prose pre {
|
||||
background: oklch(0.15 0.005 260);
|
||||
border: 1px solid oklch(from white l c h / 0.1);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
overflow-x: auto;
|
||||
font-size: 0.8125rem;
|
||||
line-height: 1.6;
|
||||
margin-top: 0.75rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.documentation-prose pre code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
font-size: inherit;
|
||||
color: oklch(0.75 0.05 200);
|
||||
}
|
||||
|
||||
.documentation-prose :not(pre) > code {
|
||||
background: oklch(from white l c h / 0.08);
|
||||
border: 1px solid oklch(from white l c h / 0.1);
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.125rem 0.375rem;
|
||||
font-size: 0.8125em;
|
||||
color: oklch(0.78 0.1 250);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* --- Lists --- */
|
||||
|
||||
.documentation-prose ol {
|
||||
list-style-type: decimal;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.documentation-prose ul {
|
||||
list-style-type: disc;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.documentation-prose li {
|
||||
margin-top: 0.25rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.documentation-prose li::marker {
|
||||
color: oklch(from white l c h / 0.4);
|
||||
}
|
||||
|
||||
/* --- Blockquotes --- */
|
||||
|
||||
.documentation-prose blockquote {
|
||||
border-left: 3px solid oklch(0.6 0.15 250);
|
||||
padding-left: 1rem;
|
||||
color: oklch(from white l c h / 0.7);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* --- Strong / Bold --- */
|
||||
|
||||
.documentation-prose strong {
|
||||
color: oklch(from white l c h / 0.95);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* --- Paragraphs --- */
|
||||
|
||||
.documentation-prose p {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
5
resources/views/components/logistics/card.blade.php
Normal file
5
resources/views/components/logistics/card.blade.php
Normal file
@@ -0,0 +1,5 @@
|
||||
@props(['class' => ''])
|
||||
|
||||
<div {{ $attributes->class(['rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10', $class]) }}>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
40
resources/views/components/logistics/data-table.blade.php
Normal file
40
resources/views/components/logistics/data-table.blade.php
Normal file
@@ -0,0 +1,40 @@
|
||||
@props(['data', 'metadata' => null, 'emptyMessage' => 'Aucun resultat.', 'emptyIcon' => 'heroicon-o-inbox'])
|
||||
|
||||
@if (count($data) > 0)
|
||||
@php
|
||||
$firstRow = reset($data);
|
||||
$isAssociative = is_array($firstRow);
|
||||
$headers = $isAssociative ? array_keys($firstRow) : [];
|
||||
@endphp
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-200 dark:border-white/10">
|
||||
@if ($isAssociative)
|
||||
@foreach ($headers as $key)
|
||||
<th class="px-3 py-2.5 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">{{ $key }}</th>
|
||||
@endforeach
|
||||
@else
|
||||
<th class="px-3 py-2.5 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">Valeur</th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100 dark:divide-white/5">
|
||||
@foreach ($data as $row)
|
||||
<tr class="transition-colors hover:bg-gray-50 dark:hover:bg-white/5">
|
||||
@if ($isAssociative)
|
||||
@foreach ($row as $value)
|
||||
<td class="px-3 py-2.5 text-sm text-gray-700 dark:text-gray-300">{{ is_array($value) ? json_encode($value) : $value }}</td>
|
||||
@endforeach
|
||||
@else
|
||||
<td class="px-3 py-2.5 text-sm text-gray-700 dark:text-gray-300">{{ $row }}</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<x-logistics.empty-state :icon="$emptyIcon" :title="$emptyMessage" />
|
||||
@endif
|
||||
@@ -0,0 +1,9 @@
|
||||
@props(['icon' => 'heroicon-o-inbox', 'title', 'description' => null])
|
||||
|
||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||
<x-filament::icon :icon="$icon" class="h-10 w-10 text-gray-300 dark:text-gray-600" />
|
||||
<p class="mt-3 text-sm font-medium text-gray-900 dark:text-white">{{ $title }}</p>
|
||||
@if ($description)
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">{{ $description }}</p>
|
||||
@endif
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
@props(['message'])
|
||||
|
||||
@if ($message)
|
||||
<div class="rounded-lg bg-danger-50 p-4 text-sm text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
|
||||
{{ $message }}
|
||||
</div>
|
||||
@endif
|
||||
11
resources/views/components/logistics/form-field.blade.php
Normal file
11
resources/views/components/logistics/form-field.blade.php
Normal file
@@ -0,0 +1,11 @@
|
||||
@props(['label', 'id', 'type' => 'text', 'placeholder' => ''])
|
||||
|
||||
<div>
|
||||
<label for="{{ $id }}" class="block text-sm font-medium text-gray-700 dark:text-gray-300">{{ $label }}</label>
|
||||
<input
|
||||
{{ $attributes->class(['mt-1.5 w-full rounded-lg border-gray-300 py-2 text-sm shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white']) }}
|
||||
type="{{ $type }}"
|
||||
id="{{ $id }}"
|
||||
placeholder="{{ $placeholder }}"
|
||||
/>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
@props(['data'])
|
||||
|
||||
@if (! empty($data))
|
||||
<div class="overflow-x-auto">
|
||||
<pre class="rounded-lg border border-gray-200 bg-gray-50 p-4 text-xs font-mono leading-relaxed text-gray-700 dark:border-white/10 dark:bg-gray-800 dark:text-gray-300">{{ json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
10
resources/views/components/logistics/search-input.blade.php
Normal file
10
resources/views/components/logistics/search-input.blade.php
Normal file
@@ -0,0 +1,10 @@
|
||||
@props(['placeholder' => 'Rechercher...'])
|
||||
|
||||
<div class="relative">
|
||||
<x-filament::icon icon="heroicon-o-magnifying-glass" class="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
|
||||
<input
|
||||
{{ $attributes->class(['w-full rounded-lg border-gray-300 py-2 pl-9 pr-3 text-sm shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white']) }}
|
||||
type="text"
|
||||
placeholder="{{ $placeholder }}"
|
||||
/>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
@props(['title', 'description' => null])
|
||||
|
||||
<div class="border-b border-gray-200 px-6 py-4 dark:border-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">{{ $title }}</h3>
|
||||
@if ($description)
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">{{ $description }}</p>
|
||||
@endif
|
||||
</div>
|
||||
@isset($actions)
|
||||
<div class="flex items-center gap-2">{{ $actions }}</div>
|
||||
@endisset
|
||||
</div>
|
||||
</div>
|
||||
5
resources/views/components/logistics/stat-bar.blade.php
Normal file
5
resources/views/components/logistics/stat-bar.blade.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<x-logistics.card>
|
||||
<div class="flex flex-wrap items-center gap-x-6 gap-y-2 px-6 py-3">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
12
resources/views/components/logistics/stat-item.blade.php
Normal file
12
resources/views/components/logistics/stat-item.blade.php
Normal file
@@ -0,0 +1,12 @@
|
||||
@props(['icon' => null, 'label' => null, 'value'])
|
||||
|
||||
<div class="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
@if ($icon)
|
||||
<x-filament::icon :icon="$icon" class="h-4 w-4 shrink-0" />
|
||||
@endif
|
||||
@if ($label)
|
||||
<span>{{ $label }} <span class="font-medium text-gray-700 dark:text-gray-200">{{ $value }}</span></span>
|
||||
@else
|
||||
<span class="font-medium text-gray-700 dark:text-gray-200">{{ $value }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@@ -1,91 +1,89 @@
|
||||
<x-filament-panels::page>
|
||||
@if ($errorMessage)
|
||||
<div class="rounded-lg bg-danger-50 p-4 text-sm text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
|
||||
{{ $errorMessage }}
|
||||
</div>
|
||||
@endif
|
||||
<x-logistics.error-banner :message="$errorMessage" />
|
||||
|
||||
{{-- Formulaire de recherche --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Rechercher des articles</h3>
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Rechercher des articles" />
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<x-logistics.form-field
|
||||
wire:model="search"
|
||||
label="Recherche"
|
||||
id="search"
|
||||
placeholder="Filtre de recherche..."
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="select"
|
||||
label="Colonnes (select)"
|
||||
id="select"
|
||||
placeholder="artid,artname"
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="results"
|
||||
label="Nombre de résultats"
|
||||
id="results"
|
||||
type="number"
|
||||
min="1"
|
||||
max="100"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<div>
|
||||
<label for="search" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Recherche</label>
|
||||
<input wire:model="search" type="text" id="search" placeholder="Filtre de recherche..."
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="select" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Colonnes (select)</label>
|
||||
<input wire:model="select" type="text" id="select" placeholder="artid,artname"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="results" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Nombre de resultats</label>
|
||||
<input wire:model="results" type="number" id="results" min="1" max="100"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
<div class="mt-4 flex items-center gap-3">
|
||||
<x-filament::button wire:click="searchArticles" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
<div wire:loading wire:target="searchArticles" class="flex items-center gap-2">
|
||||
<x-filament::loading-indicator class="h-4 w-4 text-primary-500" />
|
||||
<span class="text-sm text-gray-500">Recherche en cours...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<x-filament::button wire:click="searchArticles" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
{{-- Resultats --}}
|
||||
@if (count($data) > 0)
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Resultats</h3>
|
||||
@if ($metadata)
|
||||
<span class="text-sm text-gray-500">{{ $metadata['rowcount'] ?? 0 }} resultat(s)</span>
|
||||
@endif
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Résultats">
|
||||
<x-slot:actions>
|
||||
@if ($metadata)
|
||||
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium tabular-nums text-gray-600 dark:bg-white/10 dark:text-gray-300">
|
||||
{{ $metadata['rowcount'] ?? 0 }} résultat(s)
|
||||
</span>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
</x-logistics.section-header>
|
||||
<div class="p-6">
|
||||
<x-logistics.data-table :data="$data" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead class="border-b border-gray-200 dark:border-white/10">
|
||||
<tr>
|
||||
@foreach (array_keys(is_array(reset($data)) ? reset($data) : $data) as $key)
|
||||
<th class="px-3 py-2 font-medium text-gray-500 dark:text-gray-400">{{ $key }}</th>
|
||||
@endforeach
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100 dark:divide-white/5">
|
||||
@foreach ($data as $row)
|
||||
<tr>
|
||||
@foreach ((is_array($row) ? $row : [$row]) as $value)
|
||||
<td class="px-3 py-2 text-gray-700 dark:text-gray-300">{{ is_array($value) ? json_encode($value) : $value }}</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
@endif
|
||||
|
||||
{{-- Stock d'un article --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Verifier le stock d'un article</h3>
|
||||
|
||||
<div class="mt-4 flex items-end gap-4">
|
||||
<div class="flex-1">
|
||||
<label for="stockArticleId" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Identifiant article (ARTID)</label>
|
||||
<input wire:model="stockArticleId" type="text" id="stockArticleId" placeholder="Ex: ART001"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Vérifier le stock d'un article" />
|
||||
<div class="p-6">
|
||||
<div class="flex items-end gap-4">
|
||||
<div class="flex-1">
|
||||
<x-logistics.form-field
|
||||
wire:model="stockArticleId"
|
||||
label="Identifiant article (ARTID)"
|
||||
id="stockArticleId"
|
||||
placeholder="Ex: ART001"
|
||||
/>
|
||||
</div>
|
||||
<x-filament::button wire:click="getStock" icon="heroicon-o-cube">
|
||||
Vérifier le stock
|
||||
</x-filament::button>
|
||||
</div>
|
||||
|
||||
<div wire:loading wire:target="getStock" class="mt-4 flex items-center gap-2">
|
||||
<x-filament::loading-indicator class="h-4 w-4 text-primary-500" />
|
||||
<span class="text-sm text-gray-500">Chargement...</span>
|
||||
</div>
|
||||
|
||||
<div wire:loading.remove wire:target="getStock" class="mt-4">
|
||||
<x-logistics.json-block :data="$stockData" />
|
||||
</div>
|
||||
<x-filament::button wire:click="getStock" icon="heroicon-o-cube">
|
||||
Verifier le stock
|
||||
</x-filament::button>
|
||||
</div>
|
||||
|
||||
@if (count($stockData) > 0)
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<pre class="rounded-lg bg-gray-50 p-4 text-sm text-gray-700 dark:bg-gray-800 dark:text-gray-300">{{ json_encode($stockData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
</x-filament-panels::page>
|
||||
|
||||
170
resources/views/filament/pages/dashboard.blade.php
Normal file
170
resources/views/filament/pages/dashboard.blade.php
Normal file
@@ -0,0 +1,170 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
{{-- En-tete de bienvenue --}}
|
||||
<x-logistics.card>
|
||||
<div class="p-8 sm:p-10">
|
||||
<div class="max-w-3xl">
|
||||
<h1 class="text-2xl font-bold tracking-tight text-gray-950 sm:text-3xl dark:text-white">
|
||||
Bienvenue sur API Logistics
|
||||
</h1>
|
||||
<p class="mt-3 text-base leading-relaxed text-gray-600 dark:text-gray-400">
|
||||
Application d'exploration de l'API Logistics (Flex/ESI Gescom).
|
||||
Ce projet permet de tester les endpoints disponibles, comprendre les structures de données
|
||||
et servir de base pour une documentation complète de l'API.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
{{-- Navigation rapide --}}
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header
|
||||
title="Explorer l'API"
|
||||
description="Accédez aux différentes sections pour interroger l'API Logistics."
|
||||
/>
|
||||
<div class="grid grid-cols-1 gap-4 p-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
|
||||
<a href="{{ \App\Filament\Pages\TablesExplorer::getUrl() }}"
|
||||
class="group rounded-lg border border-gray-200 p-5 transition-colors hover:border-primary-300 hover:bg-primary-50 dark:border-white/10 dark:hover:border-primary-500/30 dark:hover:bg-primary-500/5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary-50 text-primary-600 dark:bg-primary-500/10 dark:text-primary-400">
|
||||
<x-filament::icon icon="heroicon-o-table-cells" class="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-gray-950 dark:text-white">Tables</h3>
|
||||
<p class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">Explorer les tables et leurs colonnes</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="{{ \App\Filament\Pages\Articles::getUrl() }}"
|
||||
class="group rounded-lg border border-gray-200 p-5 transition-colors hover:border-primary-300 hover:bg-primary-50 dark:border-white/10 dark:hover:border-primary-500/30 dark:hover:bg-primary-500/5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary-50 text-primary-600 dark:bg-primary-500/10 dark:text-primary-400">
|
||||
<x-filament::icon icon="heroicon-o-cube" class="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-gray-950 dark:text-white">Articles</h3>
|
||||
<p class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">Rechercher des articles et vérifier les stocks</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="{{ \App\Filament\Pages\Documents::getUrl() }}"
|
||||
class="group rounded-lg border border-gray-200 p-5 transition-colors hover:border-primary-300 hover:bg-primary-50 dark:border-white/10 dark:hover:border-primary-500/30 dark:hover:bg-primary-500/5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary-50 text-primary-600 dark:bg-primary-500/10 dark:text-primary-400">
|
||||
<x-filament::icon icon="heroicon-o-document-text" class="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-gray-950 dark:text-white">Documents</h3>
|
||||
<p class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">Consulter les documents par tiers</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="{{ \App\Filament\Pages\Journaux::getUrl() }}"
|
||||
class="group rounded-lg border border-gray-200 p-5 transition-colors hover:border-primary-300 hover:bg-primary-50 dark:border-white/10 dark:hover:border-primary-500/30 dark:hover:bg-primary-500/5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary-50 text-primary-600 dark:bg-primary-500/10 dark:text-primary-400">
|
||||
<x-filament::icon icon="heroicon-o-book-open" class="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-gray-950 dark:text-white">Journaux</h3>
|
||||
<p class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">Rechercher par type de journal</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="{{ \App\Filament\Pages\Tiers::getUrl() }}"
|
||||
class="group rounded-lg border border-gray-200 p-5 transition-colors hover:border-primary-300 hover:bg-primary-50 dark:border-white/10 dark:hover:border-primary-500/30 dark:hover:bg-primary-500/5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary-50 text-primary-600 dark:bg-primary-500/10 dark:text-primary-400">
|
||||
<x-filament::icon icon="heroicon-o-users" class="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-gray-950 dark:text-white">Tiers</h3>
|
||||
<p class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">Rechercher des tiers et leur historique</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="{{ \App\Filament\Pages\Documentation::getUrl() }}"
|
||||
class="group rounded-lg border border-gray-200 p-5 transition-colors hover:border-primary-300 hover:bg-primary-50 dark:border-white/10 dark:hover:border-primary-500/30 dark:hover:bg-primary-500/5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary-50 text-primary-600 dark:bg-primary-500/10 dark:text-primary-400">
|
||||
<x-filament::icon icon="heroicon-o-document-magnifying-glass" class="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-gray-950 dark:text-white">Documentation</h3>
|
||||
<p class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">Documentation complète de l'API</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
{{-- Informations techniques --}}
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header
|
||||
title="Informations techniques"
|
||||
description="Configuration et stack technique du projet."
|
||||
/>
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold text-gray-950 dark:text-white">Stack</h4>
|
||||
<dl class="mt-3 space-y-2 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Framework</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">Laravel 12</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Panel admin</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">Filament 5</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Composants réactifs</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">Livewire 4</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">CSS</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">Tailwind CSS 4</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Tests</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">Pest 4</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold text-gray-950 dark:text-white">Connexion API</h4>
|
||||
<dl class="mt-3 space-y-2 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Serveur</dt>
|
||||
<dd class="font-medium font-mono text-gray-700 dark:text-gray-200">tse-10-test.esi.local</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Méthode</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">POST</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Authentification</dt>
|
||||
<dd class="font-medium font-mono text-gray-700 dark:text-gray-200">X-API-KEY</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Timeout</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">{{ config('logistics.timeout', 30) }}s</dd>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<dt class="text-gray-500 dark:text-gray-400">Retry</dt>
|
||||
<dd class="font-medium text-gray-700 dark:text-gray-200">{{ config('logistics.retry.times', 3) }} tentatives</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
</x-filament-panels::page>
|
||||
9
resources/views/filament/pages/documentation.blade.php
Normal file
9
resources/views/filament/pages/documentation.blade.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<x-filament-panels::page>
|
||||
<x-logistics.card>
|
||||
<div class="p-6 sm:p-8 lg:p-10">
|
||||
<div class="documentation-prose prose prose-sm max-w-none dark:prose-invert prose-headings:scroll-mt-20">
|
||||
{!! $htmlContent !!}
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
</x-filament-panels::page>
|
||||
@@ -1,93 +1,87 @@
|
||||
<x-filament-panels::page>
|
||||
@if ($errorMessage)
|
||||
<div class="rounded-lg bg-danger-50 p-4 text-sm text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
|
||||
{{ $errorMessage }}
|
||||
</div>
|
||||
@endif
|
||||
<x-logistics.error-banner :message="$errorMessage" />
|
||||
|
||||
{{-- Formulaire de recherche --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Rechercher des documents</h3>
|
||||
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label for="select" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Colonnes (select)</label>
|
||||
<input wire:model="select" type="text" id="select" placeholder="jnl,number,thirdid,date"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Rechercher des documents" />
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<x-logistics.form-field
|
||||
wire:model="select"
|
||||
label="Colonnes (select)"
|
||||
id="select"
|
||||
placeholder="jnl,number,thirdid,date"
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="thirdId"
|
||||
label="Identifiant tiers (thirdid)"
|
||||
id="thirdId"
|
||||
placeholder="Ex: CUST001"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="thirdId" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Identifiant tiers (thirdid)</label>
|
||||
<input wire:model="thirdId" type="text" id="thirdId" placeholder="Ex: CUST001"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
|
||||
<div class="mt-4 flex items-center gap-3">
|
||||
<x-filament::button wire:click="searchDocuments" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
<div wire:loading wire:target="searchDocuments" class="flex items-center gap-2">
|
||||
<x-filament::loading-indicator class="h-4 w-4 text-primary-500" />
|
||||
<span class="text-sm text-gray-500">Recherche en cours...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<x-filament::button wire:click="searchDocuments" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
{{-- Resultats --}}
|
||||
@if (count($data) > 0)
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Resultats</h3>
|
||||
@if ($metadata)
|
||||
<span class="text-sm text-gray-500">{{ $metadata['rowcount'] ?? 0 }} resultat(s)</span>
|
||||
@endif
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Résultats">
|
||||
<x-slot:actions>
|
||||
@if ($metadata)
|
||||
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium tabular-nums text-gray-600 dark:bg-white/10 dark:text-gray-300">
|
||||
{{ $metadata['rowcount'] ?? 0 }} résultat(s)
|
||||
</span>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
</x-logistics.section-header>
|
||||
<div class="p-6">
|
||||
<x-logistics.data-table :data="$data" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead class="border-b border-gray-200 dark:border-white/10">
|
||||
<tr>
|
||||
@foreach (array_keys(is_array(reset($data)) ? reset($data) : $data) as $key)
|
||||
<th class="px-3 py-2 font-medium text-gray-500 dark:text-gray-400">{{ $key }}</th>
|
||||
@endforeach
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100 dark:divide-white/5">
|
||||
@foreach ($data as $row)
|
||||
<tr>
|
||||
@foreach ((is_array($row) ? $row : [$row]) as $value)
|
||||
<td class="px-3 py-2 text-gray-700 dark:text-gray-300">{{ is_array($value) ? json_encode($value) : $value }}</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
@endif
|
||||
|
||||
{{-- Detail d'un document --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Detail d'un document</h3>
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Détail d'un document" />
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<x-logistics.form-field
|
||||
wire:model="detailJnl"
|
||||
label="Code journal (jnl)"
|
||||
id="detailJnl"
|
||||
placeholder="Ex: VEN"
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="detailNumber"
|
||||
label="Numéro de document"
|
||||
id="detailNumber"
|
||||
placeholder="Ex: 1"
|
||||
/>
|
||||
<div class="flex items-end">
|
||||
<x-filament::button wire:click="getDocumentDetail" icon="heroicon-o-eye">
|
||||
Voir le détail
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<div>
|
||||
<label for="detailJnl" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Code journal (jnl)</label>
|
||||
<input wire:model="detailJnl" type="text" id="detailJnl" placeholder="Ex: VEN"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
<div wire:loading wire:target="getDocumentDetail" class="mt-4 flex items-center gap-2">
|
||||
<x-filament::loading-indicator class="h-4 w-4 text-primary-500" />
|
||||
<span class="text-sm text-gray-500">Chargement...</span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="detailNumber" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Numero de document</label>
|
||||
<input wire:model="detailNumber" type="text" id="detailNumber" placeholder="Ex: 1"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
</div>
|
||||
<div class="flex items-end">
|
||||
<x-filament::button wire:click="getDocumentDetail" icon="heroicon-o-eye">
|
||||
Voir le detail
|
||||
</x-filament::button>
|
||||
|
||||
<div wire:loading.remove wire:target="getDocumentDetail" class="mt-4">
|
||||
<x-logistics.json-block :data="$detailData" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (count($detailData) > 0)
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<pre class="rounded-lg bg-gray-50 p-4 text-sm text-gray-700 dark:bg-gray-800 dark:text-gray-300">{{ json_encode($detailData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
</x-filament-panels::page>
|
||||
|
||||
@@ -1,69 +1,60 @@
|
||||
<x-filament-panels::page>
|
||||
@if ($errorMessage)
|
||||
<div class="rounded-lg bg-danger-50 p-4 text-sm text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
|
||||
{{ $errorMessage }}
|
||||
</div>
|
||||
@endif
|
||||
<x-logistics.error-banner :message="$errorMessage" />
|
||||
|
||||
{{-- Formulaire de recherche --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Rechercher des journaux</h3>
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Rechercher des journaux" />
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<x-logistics.form-field
|
||||
wire:model="type"
|
||||
label="Type de journal (TYPE)"
|
||||
id="type"
|
||||
placeholder="Ex: VEN"
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="select"
|
||||
label="Colonnes (select)"
|
||||
id="select"
|
||||
placeholder="Ex: jnlid,jnlname"
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="results"
|
||||
label="Nombre de résultats"
|
||||
id="results"
|
||||
type="number"
|
||||
min="1"
|
||||
max="100"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<div>
|
||||
<label for="type" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Type de journal (TYPE)</label>
|
||||
<input wire:model="type" type="text" id="type" placeholder="Ex: VEN"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="select" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Colonnes (select)</label>
|
||||
<input wire:model="select" type="text" id="select" placeholder="Ex: jnlid,jnlname"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="results" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Nombre de resultats</label>
|
||||
<input wire:model="results" type="number" id="results" min="1" max="100"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
<div class="mt-4 flex items-center gap-3">
|
||||
<x-filament::button wire:click="searchJournaux" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
<div wire:loading wire:target="searchJournaux" class="flex items-center gap-2">
|
||||
<x-filament::loading-indicator class="h-4 w-4 text-primary-500" />
|
||||
<span class="text-sm text-gray-500">Recherche en cours...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<x-filament::button wire:click="searchJournaux" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
{{-- Resultats --}}
|
||||
@if (count($data) > 0)
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Resultats</h3>
|
||||
@if ($metadata)
|
||||
<span class="text-sm text-gray-500">{{ $metadata['rowcount'] ?? 0 }} resultat(s)</span>
|
||||
@endif
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Résultats">
|
||||
<x-slot:actions>
|
||||
@if ($metadata)
|
||||
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium tabular-nums text-gray-600 dark:bg-white/10 dark:text-gray-300">
|
||||
{{ $metadata['rowcount'] ?? 0 }} résultat(s)
|
||||
</span>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
</x-logistics.section-header>
|
||||
<div class="p-6">
|
||||
<x-logistics.data-table :data="$data" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead class="border-b border-gray-200 dark:border-white/10">
|
||||
<tr>
|
||||
@foreach (array_keys(is_array(reset($data)) ? reset($data) : $data) as $key)
|
||||
<th class="px-3 py-2 font-medium text-gray-500 dark:text-gray-400">{{ $key }}</th>
|
||||
@endforeach
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100 dark:divide-white/5">
|
||||
@foreach ($data as $row)
|
||||
<tr>
|
||||
@foreach ((is_array($row) ? $row : [$row]) as $value)
|
||||
<td class="px-3 py-2 text-gray-700 dark:text-gray-300">{{ is_array($value) ? json_encode($value) : $value }}</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
@endif
|
||||
</x-filament-panels::page>
|
||||
|
||||
@@ -1,85 +1,148 @@
|
||||
<x-filament-panels::page>
|
||||
@if ($errorMessage)
|
||||
<div class="rounded-lg bg-danger-50 p-4 text-sm text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
|
||||
{{ $errorMessage }}
|
||||
</div>
|
||||
<x-logistics.error-banner :message="$errorMessage" />
|
||||
|
||||
@if ($tablesMetadata)
|
||||
<x-logistics.stat-bar>
|
||||
<x-logistics.stat-item icon="heroicon-o-server" :value="$tablesMetadata['endpoint'] ?? '-'" />
|
||||
<x-logistics.stat-item icon="heroicon-o-circle-stack" label="Type :" :value="$tablesMetadata['folderType'] ?? '-'" />
|
||||
<x-logistics.stat-item icon="heroicon-o-table-cells" :value="($tablesMetadata['tableCount'] ?? count($tables)) . ' table(s)'" />
|
||||
</x-logistics.stat-bar>
|
||||
@endif
|
||||
|
||||
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||
{{-- Liste des tables --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Tables disponibles</h3>
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Cliquez sur une table pour voir ses colonnes.</p>
|
||||
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
||||
{{-- Panneau gauche : liste des tables --}}
|
||||
<x-logistics.card class="lg:col-span-1">
|
||||
<x-logistics.section-header
|
||||
title="Tables disponibles"
|
||||
description="Sélectionnez une table pour explorer ses colonnes."
|
||||
/>
|
||||
|
||||
<div class="mt-4 space-y-1">
|
||||
@forelse ($tables as $table)
|
||||
@if (count($tables) > 6)
|
||||
<div class="px-6 pt-4">
|
||||
<x-logistics.search-input
|
||||
wire:model.live.debounce.200ms="tableFilter"
|
||||
placeholder="Filtrer les tables..."
|
||||
/>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="max-h-[32rem] space-y-0.5 overflow-y-auto p-2">
|
||||
@forelse ($this->filteredTables as $table)
|
||||
@php
|
||||
$tableName = $table['name'] ?? '';
|
||||
$columnCount = $table['columnCount'] ?? 0;
|
||||
$isSelected = $selectedTable === $tableName;
|
||||
@endphp
|
||||
<button
|
||||
wire:click="$set('selectedTable', '{{ is_array($table) ? ($table['name'] ?? $table['tablename'] ?? '') : $table }}')"
|
||||
wire:then="loadColumns"
|
||||
class="flex w-full items-center rounded-lg px-3 py-2 text-left text-sm transition hover:bg-gray-50 dark:hover:bg-white/5 {{ $selectedTable === (is_array($table) ? ($table['name'] ?? $table['tablename'] ?? '') : $table) ? 'bg-primary-50 text-primary-600 dark:bg-primary-400/10 dark:text-primary-400' : 'text-gray-700 dark:text-gray-300' }}"
|
||||
wire:click="selectTable('{{ $tableName }}')"
|
||||
wire:key="table-{{ $tableName }}"
|
||||
@class([
|
||||
'flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-left text-sm transition-colors',
|
||||
'bg-primary-50 text-primary-700 ring-1 ring-primary-200 dark:bg-primary-400/10 dark:text-primary-400 dark:ring-primary-400/30' => $isSelected,
|
||||
'text-gray-700 hover:bg-gray-50 dark:text-gray-300 dark:hover:bg-white/5' => ! $isSelected,
|
||||
])
|
||||
>
|
||||
<x-filament::icon icon="heroicon-o-table-cells" class="mr-2 h-4 w-4" />
|
||||
{{ is_array($table) ? ($table['name'] ?? $table['tablename'] ?? json_encode($table)) : $table }}
|
||||
<div class="flex items-center gap-2.5">
|
||||
<x-filament::icon
|
||||
icon="heroicon-o-table-cells"
|
||||
@class([
|
||||
'h-4 w-4 shrink-0',
|
||||
'text-primary-500 dark:text-primary-400' => $isSelected,
|
||||
'text-gray-400' => ! $isSelected,
|
||||
])
|
||||
/>
|
||||
<span class="font-mono font-medium">{{ $tableName }}</span>
|
||||
</div>
|
||||
<span @class([
|
||||
'rounded-full px-2 py-0.5 text-xs font-medium tabular-nums',
|
||||
'bg-primary-100 text-primary-700 dark:bg-primary-400/20 dark:text-primary-300' => $isSelected,
|
||||
'bg-gray-100 text-gray-500 dark:bg-white/10 dark:text-gray-400' => ! $isSelected,
|
||||
])>
|
||||
{{ $columnCount }}
|
||||
</span>
|
||||
</button>
|
||||
@empty
|
||||
<p class="py-4 text-center text-sm text-gray-500">Aucune table trouvee. Verifiez votre cle API.</p>
|
||||
<x-logistics.empty-state
|
||||
icon="heroicon-o-table-cells"
|
||||
:title="filled($tableFilter) ? 'Aucune table ne correspond au filtre.' : 'Aucune table trouvée.'"
|
||||
:description="filled($tableFilter) ? null : 'Vérifiez votre clé API.'"
|
||||
/>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
{{-- Colonnes de la table selectionnee --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">
|
||||
Colonnes
|
||||
{{-- Panneau droit : colonnes de la table selectionnee --}}
|
||||
<x-logistics.card class="lg:col-span-2">
|
||||
<x-logistics.section-header :title="$selectedTable ? 'Colonnes de ' . $selectedTable : 'Colonnes'">
|
||||
<x-slot:actions>
|
||||
@if ($columnsMetadata && $selectedTable)
|
||||
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium tabular-nums text-gray-600 dark:bg-white/10 dark:text-gray-300">
|
||||
{{ $columnsMetadata['columnCount'] ?? count($columns) }} colonne(s)
|
||||
</span>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
</x-logistics.section-header>
|
||||
|
||||
<div class="p-6">
|
||||
@if ($selectedTable)
|
||||
<span class="text-primary-600 dark:text-primary-400">: {{ $selectedTable }}</span>
|
||||
@endif
|
||||
</h3>
|
||||
|
||||
@if ($selectedTable)
|
||||
<div class="mt-4">
|
||||
<div wire:loading wire:target="loadColumns" class="py-8 text-center text-sm text-gray-500">
|
||||
Chargement...
|
||||
<div wire:loading wire:target="selectTable" class="flex items-center justify-center py-12">
|
||||
<x-filament::loading-indicator class="h-6 w-6 text-primary-500" />
|
||||
<span class="ml-3 text-sm text-gray-500">Chargement des colonnes...</span>
|
||||
</div>
|
||||
|
||||
<div wire:loading.remove wire:target="loadColumns">
|
||||
<div wire:loading.remove wire:target="selectTable">
|
||||
@if (count($columns) > 0)
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead class="border-b border-gray-200 dark:border-white/10">
|
||||
<tr>
|
||||
@if (is_array(reset($columns)))
|
||||
@foreach (array_keys(reset($columns)) as $key)
|
||||
<th class="px-3 py-2 font-medium text-gray-500 dark:text-gray-400">{{ $key }}</th>
|
||||
@endforeach
|
||||
@else
|
||||
<th class="px-3 py-2 font-medium text-gray-500 dark:text-gray-400">Colonne</th>
|
||||
@endif
|
||||
<thead>
|
||||
<tr class="border-b border-gray-200 dark:border-white/10">
|
||||
<th class="px-3 py-2.5 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">Nom</th>
|
||||
<th class="px-3 py-2.5 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">Type</th>
|
||||
<th class="px-3 py-2.5 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">Longueur</th>
|
||||
<th class="px-3 py-2.5 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">Précision</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100 dark:divide-white/5">
|
||||
@foreach ($columns as $column)
|
||||
<tr>
|
||||
@if (is_array($column))
|
||||
@foreach ($column as $value)
|
||||
<td class="px-3 py-2 text-gray-700 dark:text-gray-300">{{ is_array($value) ? json_encode($value) : $value }}</td>
|
||||
@endforeach
|
||||
@else
|
||||
<td class="px-3 py-2 text-gray-700 dark:text-gray-300">{{ $column }}</td>
|
||||
@endif
|
||||
@php
|
||||
$dataType = strtoupper($column['dataType'] ?? '');
|
||||
$typeLabel = \App\Filament\Pages\TablesExplorer::getDataTypeLabel($dataType);
|
||||
@endphp
|
||||
<tr class="transition-colors hover:bg-gray-50 dark:hover:bg-white/5">
|
||||
<td class="px-3 py-2.5">
|
||||
<span class="font-mono text-sm font-medium text-gray-900 dark:text-white">{{ $column['name'] ?? '-' }}</span>
|
||||
</td>
|
||||
<td class="px-3 py-2.5">
|
||||
<span @class([
|
||||
'inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium ring-1 ring-inset',
|
||||
'bg-blue-50 text-blue-700 ring-blue-600/20 dark:bg-blue-400/10 dark:text-blue-400 dark:ring-blue-400/30' => $dataType === 'C',
|
||||
'bg-emerald-50 text-emerald-700 ring-emerald-600/20 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-emerald-400/30' => $dataType === 'N',
|
||||
'bg-violet-50 text-violet-700 ring-violet-600/20 dark:bg-violet-400/10 dark:text-violet-400 dark:ring-violet-400/30' => in_array($dataType, ['T', 'D']),
|
||||
'bg-amber-50 text-amber-700 ring-amber-600/20 dark:bg-amber-400/10 dark:text-amber-400 dark:ring-amber-400/30' => $dataType === 'L',
|
||||
'bg-gray-50 text-gray-700 ring-gray-600/20 dark:bg-gray-400/10 dark:text-gray-400 dark:ring-gray-400/30' => ! in_array($dataType, ['C', 'N', 'T', 'D', 'L']),
|
||||
])>
|
||||
{{ $typeLabel }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-3 py-2.5 tabular-nums text-gray-600 dark:text-gray-300">{{ $column['length'] ?? '-' }}</td>
|
||||
<td class="px-3 py-2.5 tabular-nums text-gray-600 dark:text-gray-300">{{ $column['precision'] ?? '-' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<p class="py-4 text-center text-sm text-gray-500">Aucune colonne trouvee.</p>
|
||||
<x-logistics.empty-state icon="heroicon-o-inbox" title="Aucune colonne trouvée pour cette table." />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<p class="mt-4 text-sm text-gray-500 dark:text-gray-400">Selectionnez une table pour afficher ses colonnes.</p>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<x-logistics.empty-state
|
||||
icon="heroicon-o-cursor-arrow-rays"
|
||||
title="Aucune table sélectionnée"
|
||||
description="Choisissez une table dans la liste pour afficher ses colonnes."
|
||||
/>
|
||||
@endif
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
|
||||
@@ -1,91 +1,89 @@
|
||||
<x-filament-panels::page>
|
||||
@if ($errorMessage)
|
||||
<div class="rounded-lg bg-danger-50 p-4 text-sm text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
|
||||
{{ $errorMessage }}
|
||||
</div>
|
||||
@endif
|
||||
<x-logistics.error-banner :message="$errorMessage" />
|
||||
|
||||
{{-- Formulaire de recherche --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Rechercher des tiers</h3>
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Rechercher des tiers" />
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<x-logistics.form-field
|
||||
wire:model="search"
|
||||
label="Recherche (obligatoire)"
|
||||
id="search"
|
||||
placeholder="Filtre de recherche..."
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="select"
|
||||
label="Colonnes (select)"
|
||||
id="select"
|
||||
placeholder="custid,custname"
|
||||
/>
|
||||
<x-logistics.form-field
|
||||
wire:model="results"
|
||||
label="Nombre de résultats"
|
||||
id="results"
|
||||
type="number"
|
||||
min="1"
|
||||
max="100"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
<div>
|
||||
<label for="search" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Recherche (obligatoire)</label>
|
||||
<input wire:model="search" type="text" id="search" placeholder="Filtre de recherche..."
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="select" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Colonnes (select)</label>
|
||||
<input wire:model="select" type="text" id="select" placeholder="custid,custname"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="results" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Nombre de resultats</label>
|
||||
<input wire:model="results" type="number" id="results" min="1" max="100"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
<div class="mt-4 flex items-center gap-3">
|
||||
<x-filament::button wire:click="searchTiers" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
<div wire:loading wire:target="searchTiers" class="flex items-center gap-2">
|
||||
<x-filament::loading-indicator class="h-4 w-4 text-primary-500" />
|
||||
<span class="text-sm text-gray-500">Recherche en cours...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<x-filament::button wire:click="searchTiers" icon="heroicon-o-magnifying-glass">
|
||||
Rechercher
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
|
||||
{{-- Resultats --}}
|
||||
@if (count($data) > 0)
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Resultats</h3>
|
||||
@if ($metadata)
|
||||
<span class="text-sm text-gray-500">{{ $metadata['rowcount'] ?? 0 }} resultat(s)</span>
|
||||
@endif
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Résultats">
|
||||
<x-slot:actions>
|
||||
@if ($metadata)
|
||||
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium tabular-nums text-gray-600 dark:bg-white/10 dark:text-gray-300">
|
||||
{{ $metadata['rowcount'] ?? 0 }} résultat(s)
|
||||
</span>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
</x-logistics.section-header>
|
||||
<div class="p-6">
|
||||
<x-logistics.data-table :data="$data" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead class="border-b border-gray-200 dark:border-white/10">
|
||||
<tr>
|
||||
@foreach (array_keys(is_array(reset($data)) ? reset($data) : $data) as $key)
|
||||
<th class="px-3 py-2 font-medium text-gray-500 dark:text-gray-400">{{ $key }}</th>
|
||||
@endforeach
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100 dark:divide-white/5">
|
||||
@foreach ($data as $row)
|
||||
<tr>
|
||||
@foreach ((is_array($row) ? $row : [$row]) as $value)
|
||||
<td class="px-3 py-2 text-gray-700 dark:text-gray-300">{{ is_array($value) ? json_encode($value) : $value }}</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
@endif
|
||||
|
||||
{{-- Historique des articles d'un tiers --}}
|
||||
<div class="rounded-xl bg-white p-6 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<h3 class="text-base font-semibold text-gray-950 dark:text-white">Historique des articles d'un tiers</h3>
|
||||
|
||||
<div class="mt-4 flex items-end gap-4">
|
||||
<div class="flex-1">
|
||||
<label for="historyThirdId" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Identifiant tiers (thirdid)</label>
|
||||
<input wire:model="historyThirdId" type="text" id="historyThirdId" placeholder="Ex: CUST001"
|
||||
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-white/10 dark:bg-white/5 dark:text-white sm:text-sm" />
|
||||
<x-logistics.card>
|
||||
<x-logistics.section-header title="Historique des articles d'un tiers" />
|
||||
<div class="p-6">
|
||||
<div class="flex items-end gap-4">
|
||||
<div class="flex-1">
|
||||
<x-logistics.form-field
|
||||
wire:model="historyThirdId"
|
||||
label="Identifiant tiers (thirdid)"
|
||||
id="historyThirdId"
|
||||
placeholder="Ex: CUST001"
|
||||
/>
|
||||
</div>
|
||||
<x-filament::button wire:click="getArtHistory" icon="heroicon-o-clock">
|
||||
Voir l'historique
|
||||
</x-filament::button>
|
||||
</div>
|
||||
|
||||
<div wire:loading wire:target="getArtHistory" class="mt-4 flex items-center gap-2">
|
||||
<x-filament::loading-indicator class="h-4 w-4 text-primary-500" />
|
||||
<span class="text-sm text-gray-500">Chargement...</span>
|
||||
</div>
|
||||
|
||||
<div wire:loading.remove wire:target="getArtHistory" class="mt-4">
|
||||
<x-logistics.json-block :data="$historyData" />
|
||||
</div>
|
||||
<x-filament::button wire:click="getArtHistory" icon="heroicon-o-clock">
|
||||
Voir l'historique
|
||||
</x-filament::button>
|
||||
</div>
|
||||
|
||||
@if (count($historyData) > 0)
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<pre class="rounded-lg bg-gray-50 p-4 text-sm text-gray-700 dark:bg-gray-800 dark:text-gray-300">{{ json_encode($historyData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-logistics.card>
|
||||
</x-filament-panels::page>
|
||||
|
||||
122
resources/views/pdf/documentation.blade.php
Normal file
122
resources/views/pdf/documentation.blade.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Documentation API Logistics</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: DejaVu Sans, sans-serif;
|
||||
font-size: 11px;
|
||||
line-height: 1.5;
|
||||
color: #1a1a1a;
|
||||
margin: 30px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
border-bottom: 2px solid #2563eb;
|
||||
padding-bottom: 6px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 17px;
|
||||
color: #1e40af;
|
||||
border-bottom: 1px solid #cbd5e1;
|
||||
padding-bottom: 4px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
color: #334155;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 12px;
|
||||
color: #475569;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 10px 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #cbd5e1;
|
||||
padding: 5px 8px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #e2e8f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f8fafc;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #f1f5f9;
|
||||
padding: 1px 4px;
|
||||
border-radius: 3px;
|
||||
font-family: DejaVu Sans Mono, monospace;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f1f5f9;
|
||||
border: 1px solid #e2e8f0;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
overflow-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 3px solid #2563eb;
|
||||
margin: 10px 0;
|
||||
padding: 6px 12px;
|
||||
background-color: #eff6ff;
|
||||
color: #1e40af;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #cbd5e1;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2563eb;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.page-break {
|
||||
page-break-after: always;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{!! $content !!}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user