✨ Amélioration UI + Ajout de la possibilités d'aller dans les sous dossiers
This commit is contained in:
parent
17f36e59f9
commit
1a86864dd8
3
.symfony.local.yaml
Normal file
3
.symfony.local.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
workers:
|
||||||
|
tailwind:
|
||||||
|
cmd: ['symfony', 'console', 'tailwind:build', '--watch']
|
1
assets/icons/symfony.svg
Normal file
1
assets/icons/symfony.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 257"><circle cx="128" cy="128.827" r="128" fill="#1a171b"/><path fill="#fff" d="M183.706 48.124c-12.986.453-24.32 7.61-32.757 17.51c-9.342 10.855-15.557 23.73-20.035 36.872c-8.01-6.565-14.19-15.064-27.041-18.77c-9.933-2.852-20.366-1.674-29.96 5.474c-4.545 3.395-7.676 8.527-9.165 13.351c-3.855 12.537 4.053 23.694 7.645 27.7l7.853 8.416c1.619 1.65 5.518 5.955 3.612 12.127c-2.06 6.71-10.15 11.055-18.448 8.495c-3.706-1.13-9.03-3.891-7.838-7.779c.493-1.59 1.631-2.78 2.241-4.155c.56-1.181.827-2.067.997-2.587c1.516-4.95-.555-11.39-5.857-13.025c-4.946-1.516-10.007-.315-11.969 6.054c-2.225 7.235 1.237 20.366 19.783 26.084c21.729 6.676 40.11-5.155 42.717-20.586c1.642-9.665-2.722-16.845-10.717-26.08l-6.514-7.204c-3.946-3.942-5.301-10.661-1.217-15.825c3.446-4.356 8.354-6.215 16.392-4.029c11.733 3.186 16.963 11.327 25.69 17.893c-3.603 11.819-5.958 23.682-8.09 34.32l-1.299 7.931c-6.238 32.721-11 50.688-23.375 61.003c-2.493 1.773-6.057 4.427-11.429 4.612c-2.816.087-3.726-1.85-3.765-2.694c-.067-1.977 1.599-2.883 2.706-3.773c1.654-.902 4.155-2.398 3.985-7.191c-.18-5.664-4.872-10.575-11.654-10.35c-5.08.173-12.823 4.954-12.532 13.705c.303 9.039 8.728 15.813 21.43 15.384c6.79-.233 21.952-2.997 36.895-20.76c17.392-20.362 22.256-43.705 25.915-60.79l4.084-22.556c2.269.272 4.695.453 7.334.516c21.661.457 32.496-10.763 32.657-18.924c.107-4.939-3.241-9.799-7.928-9.689c-3.355.095-7.57 2.328-8.582 6.968c-.988 4.552 6.893 8.66.733 12.65c-4.376 2.832-12.221 4.828-23.269 3.206l2.009-11.103c4.1-21.055 9.157-46.954 28.341-47.584c1.398-.071 6.514.063 6.633 3.446c.035 1.13-.245 1.418-1.568 4.005c-1.347 2.017-1.855 3.734-1.792 5.707c.185 5.376 4.273 8.909 10.185 8.696c7.916-.256 10.193-7.963 10.063-11.921c-.32-9.3-10.122-15.175-23.1-14.75"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/images/favicon.ico
Normal file
BIN
assets/images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
BIN
assets/images/logo.png
Normal file
BIN
assets/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 814 KiB |
@ -40,7 +40,9 @@
|
|||||||
"symfony/string": "7.2.*",
|
"symfony/string": "7.2.*",
|
||||||
"symfony/translation": "7.2.*",
|
"symfony/translation": "7.2.*",
|
||||||
"symfony/twig-bundle": "7.2.*",
|
"symfony/twig-bundle": "7.2.*",
|
||||||
|
"symfony/ux-icons": "^2.22",
|
||||||
"symfony/ux-turbo": "^2.22",
|
"symfony/ux-turbo": "^2.22",
|
||||||
|
"symfony/ux-twig-component": "^2.22",
|
||||||
"symfony/validator": "7.2.*",
|
"symfony/validator": "7.2.*",
|
||||||
"symfony/web-link": "7.2.*",
|
"symfony/web-link": "7.2.*",
|
||||||
"symfony/yaml": "7.2.*",
|
"symfony/yaml": "7.2.*",
|
||||||
|
174
composer.lock
generated
174
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "c8e8b543137984b211315030412feaf7",
|
"content-hash": "b7708b5019145d17ad3512f8c441f6bc",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
@ -7123,6 +7123,95 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-12-11T07:49:41+00:00"
|
"time": "2024-12-11T07:49:41+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/ux-icons",
|
||||||
|
"version": "v2.22.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/ux-icons.git",
|
||||||
|
"reference": "3a6fd4293fc200530b09960c41941a71354bc5fc"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/ux-icons/zipball/3a6fd4293fc200530b09960c41941a71354bc5fc",
|
||||||
|
"reference": "3a6fd4293fc200530b09960c41941a71354bc5fc",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.1",
|
||||||
|
"symfony/framework-bundle": "^6.4|^7.0",
|
||||||
|
"symfony/twig-bundle": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/flex": "<1.13",
|
||||||
|
"symfony/ux-twig-component": "<2.21"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"psr/log": "^2|^3",
|
||||||
|
"symfony/asset-mapper": "^6.4|^7.0",
|
||||||
|
"symfony/console": "^6.4|^7.0",
|
||||||
|
"symfony/http-client": "6.4|^7.0",
|
||||||
|
"symfony/phpunit-bridge": "^6.3|^7.0",
|
||||||
|
"symfony/ux-twig-component": "^2.14",
|
||||||
|
"zenstruck/console-test": "^1.5"
|
||||||
|
},
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/ux",
|
||||||
|
"name": "symfony/ux"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\UX\\Icons\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Kevin Bond",
|
||||||
|
"email": "kevinbond@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Simon André",
|
||||||
|
"email": "smn.andre@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Renders local and remote SVG icons in your Twig templates.",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"icons",
|
||||||
|
"svg",
|
||||||
|
"symfony-ux",
|
||||||
|
"twig"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/ux-icons/tree/v2.22.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-12-04T11:34:13+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/ux-turbo",
|
"name": "symfony/ux-turbo",
|
||||||
"version": "v2.22.1",
|
"version": "v2.22.1",
|
||||||
@ -7221,6 +7310,89 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-12-05T14:25:02+00:00"
|
"time": "2024-12-05T14:25:02+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/ux-twig-component",
|
||||||
|
"version": "v2.22.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/ux-twig-component.git",
|
||||||
|
"reference": "9b347f6ca2d9e18cee630787f0a6aa453982bf18"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/9b347f6ca2d9e18cee630787f0a6aa453982bf18",
|
||||||
|
"reference": "9b347f6ca2d9e18cee630787f0a6aa453982bf18",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.1",
|
||||||
|
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/deprecation-contracts": "^2.2|^3.0",
|
||||||
|
"symfony/event-dispatcher": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/property-access": "^5.4|^6.0|^7.0",
|
||||||
|
"twig/twig": "^3.8"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/config": "<5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/console": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/css-selector": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/dom-crawler": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/framework-bundle": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/phpunit-bridge": "^6.0|^7.0",
|
||||||
|
"symfony/stimulus-bundle": "^2.9.1",
|
||||||
|
"symfony/twig-bundle": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/webpack-encore-bundle": "^1.15"
|
||||||
|
},
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/ux",
|
||||||
|
"name": "symfony/ux"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\UX\\TwigComponent\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Twig components for Symfony",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"components",
|
||||||
|
"symfony-ux",
|
||||||
|
"twig"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/ux-twig-component/tree/v2.22.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-12-07T18:05:50+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/validator",
|
"name": "symfony/validator",
|
||||||
"version": "v7.2.0",
|
"version": "v7.2.0",
|
||||||
|
@ -15,4 +15,6 @@ return [
|
|||||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||||
Symfonycasts\TailwindBundle\SymfonycastsTailwindBundle::class => ['all' => true],
|
Symfonycasts\TailwindBundle\SymfonycastsTailwindBundle::class => ['all' => true],
|
||||||
Oneup\FlysystemBundle\OneupFlysystemBundle::class => ['all' => true],
|
Oneup\FlysystemBundle\OneupFlysystemBundle::class => ['all' => true],
|
||||||
|
Symfony\UX\Icons\UXIconsBundle::class => ['all' => true],
|
||||||
|
Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
5
config/packages/twig_component.yaml
Normal file
5
config/packages/twig_component.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
twig_component:
|
||||||
|
anonymous_template_directory: 'components/'
|
||||||
|
defaults:
|
||||||
|
# Namespace & directory for components
|
||||||
|
App\Twig\Components\: 'components/'
|
@ -3,6 +3,8 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use League\Flysystem\Filesystem;
|
use League\Flysystem\Filesystem;
|
||||||
|
use League\Flysystem\FilesystemException;
|
||||||
|
use League\Flysystem\FilesystemReader;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
@ -13,25 +15,53 @@ use Symfony\Component\HttpFoundation\HeaderUtils;
|
|||||||
|
|
||||||
class DashboardController extends AbstractController
|
class DashboardController extends AbstractController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws FilesystemException
|
||||||
|
*/
|
||||||
#[Route('/', name: 'app_dashboard')]
|
#[Route('/', name: 'app_dashboard')]
|
||||||
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator): Response
|
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator, #[MapQueryParameter('path')] string $path = ''): Response
|
||||||
{
|
{
|
||||||
$files = $defaultAdapter->listContents('/', Filesystem::LIST_DEEP);
|
// On retire les slashs en début et fin de chaîne
|
||||||
|
$path = trim($path, '/');
|
||||||
|
// On retire les chemins relatifs
|
||||||
|
$path = str_replace('..', '', $path);
|
||||||
|
$path = str_replace('//', '/', $path);
|
||||||
|
|
||||||
|
if ($path !== '' && !$defaultAdapter->directoryExists($path)) {
|
||||||
|
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$files = $defaultAdapter->listContents('/' . $path);
|
||||||
|
|
||||||
$realFiles = [];
|
$realFiles = [];
|
||||||
|
|
||||||
foreach ($files as $key => $file) {
|
foreach ($files as $file) {
|
||||||
if ($file['type'] === 'file' && !str_starts_with($file['path'], '.')) {
|
if (!str_starts_with($file['path'], '.')) {
|
||||||
$realFiles[] = [
|
$realFiles[] = [
|
||||||
|
'type' => $file['type'],
|
||||||
'path' => $file['path'],
|
'path' => $file['path'],
|
||||||
'url' => $this->generateUrl('app_file_proxy', ['filename' => $file['path']], UrlGeneratorInterface::ABSOLUTE_URL),
|
'last_modified' => $file['lastModified'],
|
||||||
|
'size' => $file['fileSize'] ?? null,
|
||||||
|
'url' => $file['type'] === 'file'
|
||||||
|
? $this->generateUrl('app_file_proxy', ['filename' => $file['path']], UrlGeneratorInterface::ABSOLUTE_URL)
|
||||||
|
: $this->generateUrl('app_dashboard', ['path' => $path . '/' . $file['path']]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On trie par type puis par nom
|
||||||
|
usort($realFiles, static function ($a, $b) {
|
||||||
|
if ($a['type'] === $b['type']) {
|
||||||
|
return $a['path'] <=> $b['path'];
|
||||||
|
} else {
|
||||||
|
return $a['type'] <=> $b['type'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return $this->render('dashboard/index.html.twig', [
|
return $this->render('dashboard/index.html.twig', [
|
||||||
'files' => $realFiles,
|
'files' => $realFiles,
|
||||||
|
'path' => $path,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
src/Twig/Extension/BasenameExtension.php
Normal file
18
src/Twig/Extension/BasenameExtension.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig\Extension;
|
||||||
|
|
||||||
|
use App\Twig\Runtime\BasenameExtensionRuntime;
|
||||||
|
use Twig\Extension\AbstractExtension;
|
||||||
|
use Twig\TwigFilter;
|
||||||
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
|
class BasenameExtension extends AbstractExtension
|
||||||
|
{
|
||||||
|
public function getFilters(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFilter('basename', [BasenameExtensionRuntime::class, 'basename']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
18
src/Twig/Extension/SizeExtension.php
Normal file
18
src/Twig/Extension/SizeExtension.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig\Extension;
|
||||||
|
|
||||||
|
use App\Twig\Runtime\SizeExtensionRuntime;
|
||||||
|
use Twig\Extension\AbstractExtension;
|
||||||
|
use Twig\TwigFilter;
|
||||||
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
|
class SizeExtension extends AbstractExtension
|
||||||
|
{
|
||||||
|
public function getFilters(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFilter('show_size', [SizeExtensionRuntime::class, 'showSize']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
21
src/Twig/Extension/TimeExtension.php
Normal file
21
src/Twig/Extension/TimeExtension.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig\Extension;
|
||||||
|
|
||||||
|
use App\Twig\Runtime\TimeExtensionRuntime;
|
||||||
|
use Twig\Extension\AbstractExtension;
|
||||||
|
use Twig\TwigFilter;
|
||||||
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
|
class TimeExtension extends AbstractExtension
|
||||||
|
{
|
||||||
|
public function getFilters(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// If your filter generates SAFE HTML, you should add a third
|
||||||
|
// parameter: ['is_safe' => ['html']]
|
||||||
|
// Reference: https://twig.symfony.com/doc/3.x/advanced.html#automatic-escaping
|
||||||
|
new TwigFilter('time_diff', [TimeExtensionRuntime::class, 'timeDiff']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
14
src/Twig/Runtime/BasenameExtensionRuntime.php
Normal file
14
src/Twig/Runtime/BasenameExtensionRuntime.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig\Runtime;
|
||||||
|
|
||||||
|
use Twig\Extension\RuntimeExtensionInterface;
|
||||||
|
|
||||||
|
class BasenameExtensionRuntime implements RuntimeExtensionInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public function basename($value)
|
||||||
|
{
|
||||||
|
return \basename($value);
|
||||||
|
}
|
||||||
|
}
|
22
src/Twig/Runtime/SizeExtensionRuntime.php
Normal file
22
src/Twig/Runtime/SizeExtensionRuntime.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig\Runtime;
|
||||||
|
|
||||||
|
use Twig\Extension\RuntimeExtensionInterface;
|
||||||
|
|
||||||
|
class SizeExtensionRuntime implements RuntimeExtensionInterface
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// Inject dependencies if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
public function showSize($value)
|
||||||
|
{
|
||||||
|
$bytes = $value;
|
||||||
|
$size = ['B', 'KB', 'MB', 'GB','TB'];
|
||||||
|
$factor = floor((strlen($bytes) - 1) / 3);
|
||||||
|
|
||||||
|
return sprintf('%.1f', $bytes / pow(1024, $factor)) . ' ' . @$size[$factor];
|
||||||
|
}
|
||||||
|
}
|
40
src/Twig/Runtime/TimeExtensionRuntime.php
Normal file
40
src/Twig/Runtime/TimeExtensionRuntime.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig\Runtime;
|
||||||
|
|
||||||
|
use Twig\Extension\RuntimeExtensionInterface;
|
||||||
|
|
||||||
|
class TimeExtensionRuntime implements RuntimeExtensionInterface
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// Inject dependencies if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
public function timeDiff($value): string
|
||||||
|
{
|
||||||
|
$now = time();
|
||||||
|
$diff = $now - $value;
|
||||||
|
|
||||||
|
// Moins d'une minute
|
||||||
|
if ($diff < 60) {
|
||||||
|
return 'Il y a ' . $diff . ' seconde' . ($diff > 1 ? 's' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moins d'une heure
|
||||||
|
if ($diff < 3600) {
|
||||||
|
$minutes = floor($diff / 60);
|
||||||
|
return 'Il y a ' . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moins d'un jour
|
||||||
|
if ($diff < 86400) {
|
||||||
|
$hours = floor($diff / 3600);
|
||||||
|
return 'Il y a ' . $hours . ' heure' . ($hours > 1 ? 's' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plus d'un jour
|
||||||
|
$days = floor($diff / 86400);
|
||||||
|
return 'Il y a ' . $days . ' jour' . ($days > 1 ? 's' : '');
|
||||||
|
}
|
||||||
|
}
|
24
symfony.lock
24
symfony.lock
@ -274,6 +274,18 @@
|
|||||||
"templates/base.html.twig"
|
"templates/base.html.twig"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"symfony/ux-icons": {
|
||||||
|
"version": "2.22",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "2.17",
|
||||||
|
"ref": "803a3bbd5893f9584969ab8670290cdfb6a0a5b5"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"assets/icons/symfony.svg"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/ux-turbo": {
|
"symfony/ux-turbo": {
|
||||||
"version": "2.22",
|
"version": "2.22",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
@ -283,6 +295,18 @@
|
|||||||
"ref": "c85ff94da66841d7ff087c19cbcd97a2df744ef9"
|
"ref": "c85ff94da66841d7ff087c19cbcd97a2df744ef9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"symfony/ux-twig-component": {
|
||||||
|
"version": "2.22",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "2.13",
|
||||||
|
"ref": "67814b5f9794798b885cec9d3f48631424449a01"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/twig_component.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/validator": {
|
"symfony/validator": {
|
||||||
"version": "7.2",
|
"version": "7.2",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="fr" class="bg-white dark:bg-gray-800 dark:text-white">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Kumora - {% block title %}Accueil{% endblock %}</title>
|
<title>Kumora - {% block title %}Accueil{% endblock %}</title>
|
||||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
|
<link rel="icon" href="{{ asset('images/favicon.ico') }}">
|
||||||
{% block stylesheets %}
|
{% block stylesheets %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -4,11 +4,66 @@
|
|||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="container mx-auto px-16">
|
<div class="container mx-auto px-16">
|
||||||
<h1 class="text-center text-2xl font-bold">Bienvenue sur le dashboard</h1>
|
<h1 class="text-center text-2xl font-bold mt-4">Liste des fichiers</h1>
|
||||||
<ul class="list-disc">
|
<div class="mt-4">
|
||||||
{% for item in files %}
|
{% include 'partials/breadbrumb.html.twig' %}
|
||||||
<li><a class="text-blue-500 hover:text-blue-700" href="{{ item.url }}">/{{ item.path }}</a></li>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="relative overflow-x-auto mt-4">
|
||||||
|
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
||||||
|
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="px-6 py-3">
|
||||||
|
Nom
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-3">
|
||||||
|
Taille
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-3">
|
||||||
|
Modifié le
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-3">
|
||||||
|
Action
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for file in files %}
|
||||||
|
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<th class="px-6 py-4 font-medium light:text-gray-900 whitespace-nowrap flex gap-2">
|
||||||
|
{% if file.type == 'file' %}
|
||||||
|
<twig:ux:icon name="line-md:file-filled" class="w-6 h-6" />
|
||||||
|
{% else %}
|
||||||
|
<twig:ux:icon name="line-md:folder-filled" class="w-6 h-6" />
|
||||||
|
{% endif %}
|
||||||
|
<a class="text-blue-700 dark:text-blue-500 hover:text-blue-900 dark:hover:text-blue-700" href="{{ file.url }}">{{ file.path|basename }}</a>
|
||||||
|
</th>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
{% if file.type == 'file' %}
|
||||||
|
{{ file.size|show_size }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
{{ file.last_modified|time_diff }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 flex gap-2 light:text-black">
|
||||||
|
{% if file.type == 'file' %}
|
||||||
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:eye" /></a>
|
||||||
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:download" /></a>
|
||||||
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:link" /></a>
|
||||||
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
||||||
|
<a href="#" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:link" /></a>
|
||||||
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
||||||
|
<a href="#" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
33
templates/partials/breadbrumb.html.twig
Normal file
33
templates/partials/breadbrumb.html.twig
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<nav class="flex" aria-label="Breadcrumb">
|
||||||
|
<ol class="inline-flex items-center space-x-1 md:space-x-2 rtl:space-x-reverse {{ path == '' ? 'my-1' : '' }}">
|
||||||
|
<li class="flex items-center">
|
||||||
|
<a href="{{ path('app_dashboard') }}"
|
||||||
|
class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600 dark:text-gray-400 dark:hover:text-white">
|
||||||
|
<twig:ux:icon class="w-3 h-3" name="fa6-solid:house"/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% if path != '' %}
|
||||||
|
{% set pathSplitted = path|split('/') %}
|
||||||
|
{% for pa in pathSplitted %}
|
||||||
|
{% if loop.last %}
|
||||||
|
<li aria-current="page">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<twig:ux:icon class="rtl:rotate-180 w-3 h-3 text-gray-400 mx-1"
|
||||||
|
name="fa6-solid:chevron-right"/>
|
||||||
|
<span class="ms-1 text-sm font-medium text-gray-500 md:ms-2 dark:text-gray-400">{{ pa }}</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<twig:ux:icon class="rtl:rotate-180 w-3 h-3 text-gray-400 mx-1"
|
||||||
|
name="fa6-solid:chevron-right"/>
|
||||||
|
<a href="#"
|
||||||
|
class="ms-1 text-sm font-medium text-gray-700 hover:text-blue-600 md:ms-2 dark:text-gray-400 dark:hover:text-white">{{ pa }}</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
@ -1,6 +1,34 @@
|
|||||||
<nav>
|
<nav class="bg-white border-gray-200 dark:bg-gray-900">
|
||||||
<ul>
|
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
|
||||||
<li>Accueil</li>
|
<a href="{{ path('app_dashboard') }}" class="flex items-center space-x-3 rtl:space-x-reverse">
|
||||||
<li>Liste des fichiers</li>
|
<img src="{{ asset('images/logo.png') }}" class="h-8" alt="Logo Camélia-Studio" />
|
||||||
|
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white">Kumora</span>
|
||||||
|
</a>
|
||||||
|
<button data-collapse-toggle="navbar-default" type="button" class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600" aria-controls="navbar-default" aria-expanded="false">
|
||||||
|
<span class="sr-only">Open main menu</span>
|
||||||
|
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 17 14">
|
||||||
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div class="hidden w-full md:block md:w-auto" id="navbar-default">
|
||||||
|
<ul class="font-medium flex flex-col p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 rtl:space-x-reverse md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
|
||||||
|
<li>
|
||||||
|
<a href="#" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">Accueil</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">Liste des fichiers</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">Administration</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">Se connecter</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">S'inscrire</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user