ajout de la partie publique
This commit is contained in:
parent
c6af349844
commit
bd1bb9bb36
100
albums.php
Normal file
100
albums.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'fonctions.php';
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// Récupérer le chemin actuel depuis l'URL
|
||||||
|
$currentPath = isset($_GET['path']) ? $_GET['path'] : './liste_albums';
|
||||||
|
$currentPath = realpath($currentPath);
|
||||||
|
|
||||||
|
// Vérification de sécurité
|
||||||
|
if (!isSecurePath($currentPath)) {
|
||||||
|
header('Location: index.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupérer tous les sous-dossiers
|
||||||
|
$albums = [];
|
||||||
|
foreach (new DirectoryIterator($currentPath) as $item) {
|
||||||
|
if ($item->isDot()) continue;
|
||||||
|
if ($item->isDir()) {
|
||||||
|
$albumPath = $item->getPathname();
|
||||||
|
$info = getAlbumInfo($albumPath);
|
||||||
|
|
||||||
|
$images = hasSubfolders($albumPath) ?
|
||||||
|
getImagesRecursively($albumPath) :
|
||||||
|
getLatestImages($albumPath);
|
||||||
|
|
||||||
|
$albums[] = [
|
||||||
|
'path' => str_replace('\\', '/', $albumPath),
|
||||||
|
'title' => $info['title'],
|
||||||
|
'description' => $info['description'],
|
||||||
|
'images' => $images,
|
||||||
|
'hasSubfolders' => hasSubfolders($albumPath),
|
||||||
|
'hasImages' => hasImages($albumPath)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Déterminer le chemin parent pour le bouton retour
|
||||||
|
$parentPath = dirname($currentPath);
|
||||||
|
if (!isSecurePath($parentPath)) {
|
||||||
|
$parentPath = null;
|
||||||
|
}
|
||||||
|
?><!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Albums - ICO</title>
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body class="albums-page">
|
||||||
|
<?php if ($parentPath): ?>
|
||||||
|
<a href="?path=<?php echo urlencode($parentPath); ?>" class="back-button">Retour</a>
|
||||||
|
<?php else: ?>
|
||||||
|
<a href="index.php" class="back-button">Retour</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="albums-grid">
|
||||||
|
<?php foreach ($albums as $album): ?>
|
||||||
|
<a href="<?php echo $album['hasSubfolders'] ? 'albums.php' : 'galeries.php'; ?>?path=<?php echo urlencode($album['path']); ?>"
|
||||||
|
class="album-card">
|
||||||
|
<div class="album-images">
|
||||||
|
<?php if (empty($album['images'])): ?>
|
||||||
|
<div class="empty-album"></div>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($album['images'] as $index => $image): ?>
|
||||||
|
<div class="album-image" style="background-image: url('<?php echo htmlspecialchars($image); ?>')"></div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php for ($i = count($album['images']); $i < 4; $i++): ?>
|
||||||
|
<div class="empty-image"></div>
|
||||||
|
<?php endfor; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<div class="album-info">
|
||||||
|
<h2><?php echo htmlspecialchars($album['title']); ?></h2>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const observer = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
entry.target.classList.add('visible');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
threshold: 0.1
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.album-card').forEach(card => {
|
||||||
|
observer.observe(card);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
favicon.png
Normal file
BIN
favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
204
fonctions.php
Normal file
204
fonctions.php
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
<?php
|
||||||
|
// Configuration
|
||||||
|
define('PROJECT_ROOT_DIR', 'test-ico');
|
||||||
|
define('ALLOWED_EXTENSIONS', ['jpg', 'jpeg', 'png', 'gif']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtient l'URL de base du site
|
||||||
|
* @return string L'URL de base du site
|
||||||
|
*/
|
||||||
|
function getBaseUrl() {
|
||||||
|
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
|
||||||
|
return $protocol . $_SERVER['HTTP_HOST'] . '/' . PROJECT_ROOT_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère les informations d'un album depuis son fichier infos.txt
|
||||||
|
* @param string $albumPath Chemin vers l'album
|
||||||
|
* @return array Tableau contenant le titre et la description de l'album
|
||||||
|
*/
|
||||||
|
function getAlbumInfo($albumPath) {
|
||||||
|
$infoFile = $albumPath . '/infos.txt';
|
||||||
|
$info = [
|
||||||
|
'title' => basename($albumPath),
|
||||||
|
'description' => ''
|
||||||
|
];
|
||||||
|
|
||||||
|
if (file_exists($infoFile)) {
|
||||||
|
$content = file_get_contents($infoFile);
|
||||||
|
$lines = explode("\n", $content);
|
||||||
|
if (isset($lines[0])) $info['title'] = trim($lines[0]);
|
||||||
|
if (isset($lines[1])) $info['description'] = trim($lines[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère les dernières images d'un dossier
|
||||||
|
* @param string $albumPath Chemin vers l'album
|
||||||
|
* @param int $limit Nombre d'images à récupérer
|
||||||
|
* @return array Tableau des URLs des images
|
||||||
|
*/
|
||||||
|
function getLatestImages($albumPath, $limit = 4) {
|
||||||
|
$images = [];
|
||||||
|
$baseUrl = getBaseUrl();
|
||||||
|
|
||||||
|
if (!is_dir($albumPath)) return $images;
|
||||||
|
|
||||||
|
foreach (new DirectoryIterator($albumPath) as $file) {
|
||||||
|
if ($file->isDot()) continue;
|
||||||
|
if ($file->isFile()) {
|
||||||
|
$extension = strtolower($file->getExtension());
|
||||||
|
if (in_array($extension, ALLOWED_EXTENSIONS)) {
|
||||||
|
$relativePath = str_replace('\\', '/', substr($file->getPathname(), strlen(realpath('./'))));
|
||||||
|
$images[] = $baseUrl . '/' . ltrim($relativePath, '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($images, function($a, $b) {
|
||||||
|
$pathA = realpath('.') . str_replace(getBaseUrl(), '', $a);
|
||||||
|
$pathB = realpath('.') . str_replace(getBaseUrl(), '', $b);
|
||||||
|
return filectime($pathB) - filectime($pathA);
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_slice($images, 0, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère les images de manière récursive dans tous les sous-dossiers
|
||||||
|
* @param string $albumPath Chemin vers l'album
|
||||||
|
* @param int $limit Nombre d'images à récupérer
|
||||||
|
* @return array Tableau des URLs des images
|
||||||
|
*/
|
||||||
|
function getImagesRecursively($albumPath, $limit = 4) {
|
||||||
|
$images = [];
|
||||||
|
$baseUrl = getBaseUrl();
|
||||||
|
|
||||||
|
if (!is_dir($albumPath)) return $images;
|
||||||
|
|
||||||
|
$iterator = new RecursiveIteratorIterator(
|
||||||
|
new RecursiveDirectoryIterator($albumPath),
|
||||||
|
RecursiveIteratorIterator::SELF_FIRST
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($iterator as $file) {
|
||||||
|
if ($file->isFile()) {
|
||||||
|
$extension = strtolower($file->getExtension());
|
||||||
|
if (in_array($extension, ALLOWED_EXTENSIONS)) {
|
||||||
|
$relativePath = str_replace('\\', '/', substr($file->getPathname(), strlen(realpath('./'))));
|
||||||
|
$images[] = $baseUrl . '/' . ltrim($relativePath, '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($images, function($a, $b) {
|
||||||
|
$pathA = realpath('.') . str_replace(getBaseUrl(), '', $a);
|
||||||
|
$pathB = realpath('.') . str_replace(getBaseUrl(), '', $b);
|
||||||
|
return filectime($pathB) - filectime($pathA);
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_slice($images, 0, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si un dossier contient des sous-dossiers
|
||||||
|
* @param string $path Chemin du dossier
|
||||||
|
* @return bool True si le dossier contient des sous-dossiers
|
||||||
|
*/
|
||||||
|
function hasSubfolders($path) {
|
||||||
|
if (!is_dir($path)) return false;
|
||||||
|
|
||||||
|
foreach (new DirectoryIterator($path) as $item) {
|
||||||
|
if ($item->isDot()) continue;
|
||||||
|
if ($item->isDir()) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si un dossier contient des images
|
||||||
|
* @param string $path Chemin du dossier
|
||||||
|
* @return bool True si le dossier contient des images
|
||||||
|
*/
|
||||||
|
function hasImages($path) {
|
||||||
|
if (!is_dir($path)) return false;
|
||||||
|
|
||||||
|
foreach (new DirectoryIterator($path) as $item) {
|
||||||
|
if ($item->isDot()) continue;
|
||||||
|
if ($item->isFile()) {
|
||||||
|
$extension = strtolower($item->getExtension());
|
||||||
|
if (in_array($extension, ALLOWED_EXTENSIONS)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si le chemin est sécurisé (dans le dossier liste_albums)
|
||||||
|
* @param string $path Chemin à vérifier
|
||||||
|
* @return bool True si le chemin est sécurisé
|
||||||
|
*/
|
||||||
|
function isSecurePath($path) {
|
||||||
|
$realPath = realpath($path);
|
||||||
|
$rootPath = realpath('./liste_albums');
|
||||||
|
return $realPath && strpos($realPath, $rootPath) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formate la taille d'un fichier en format lisible
|
||||||
|
* @param int $bytes Taille en octets
|
||||||
|
* @return string Taille formatée (ex: "1.2 MB")
|
||||||
|
*/
|
||||||
|
function formatFileSize($bytes) {
|
||||||
|
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||||
|
$bytes = max($bytes, 0);
|
||||||
|
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||||
|
$pow = min($pow, count($units) - 1);
|
||||||
|
$bytes /= pow(1024, $pow);
|
||||||
|
return round($bytes, 1) . ' ' . $units[$pow];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère les dimensions d'une image de manière sécurisée
|
||||||
|
* @param string $path Chemin vers l'image
|
||||||
|
* @return array|false Tableau contenant width et height ou false en cas d'erreur
|
||||||
|
*/
|
||||||
|
function getSecureImageSize($path) {
|
||||||
|
try {
|
||||||
|
if (!file_exists($path)) return false;
|
||||||
|
$imageInfo = getimagesize($path);
|
||||||
|
if ($imageInfo === false) return false;
|
||||||
|
return [
|
||||||
|
'width' => $imageInfo[0],
|
||||||
|
'height' => $imageInfo[1]
|
||||||
|
];
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Génère un identifiant unique sécurisé
|
||||||
|
* @param int $length Longueur de l'identifiant
|
||||||
|
* @return string Identifiant unique
|
||||||
|
*/
|
||||||
|
function generateSecureId($length = 32) {
|
||||||
|
return bin2hex(random_bytes($length / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nettoie et sécurise un nom de fichier
|
||||||
|
* @param string $filename Nom du fichier à nettoyer
|
||||||
|
* @return string Nom de fichier sécurisé
|
||||||
|
*/
|
||||||
|
function sanitizeFilename($filename) {
|
||||||
|
// Supprime les caractères spéciaux
|
||||||
|
$filename = preg_replace('/[^a-zA-Z0-9._-]/', '-', $filename);
|
||||||
|
// Évite les noms de fichiers commençant par un point
|
||||||
|
$filename = ltrim($filename, '.');
|
||||||
|
// Limite la longueur du nom de fichier
|
||||||
|
return substr($filename, 0, 255);
|
||||||
|
}
|
||||||
|
?>
|
110
galeries.php
Normal file
110
galeries.php
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'fonctions.php';
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// Récupérer le chemin actuel depuis l'URL
|
||||||
|
$currentPath = isset($_GET['path']) ? $_GET['path'] : './liste_albums';
|
||||||
|
$currentPath = realpath($currentPath);
|
||||||
|
|
||||||
|
// Vérification de sécurité
|
||||||
|
if (!isSecurePath($currentPath)) {
|
||||||
|
header('Location: index.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$albumInfo = getAlbumInfo($currentPath);
|
||||||
|
$images = [];
|
||||||
|
$baseUrl = getBaseUrl();
|
||||||
|
|
||||||
|
foreach (new DirectoryIterator($currentPath) as $file) {
|
||||||
|
if ($file->isDot()) continue;
|
||||||
|
if ($file->isFile()) {
|
||||||
|
$extension = strtolower($file->getExtension());
|
||||||
|
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||||
|
$relativePath = str_replace('\\', '/', substr($file->getPathname(), strlen(realpath('./'))));
|
||||||
|
$url = $baseUrl . '/' . ltrim($relativePath, '/');
|
||||||
|
$images[] = $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($images, function($a, $b) {
|
||||||
|
$pathA = realpath('.') . str_replace(getBaseUrl(), '', $a);
|
||||||
|
$pathB = realpath('.') . str_replace(getBaseUrl(), '', $b);
|
||||||
|
return filectime($pathB) - filectime($pathA);
|
||||||
|
});
|
||||||
|
|
||||||
|
$headerImage = !empty($images) ? $images[0] : null;
|
||||||
|
|
||||||
|
$parentPath = dirname($currentPath);
|
||||||
|
if (!isSecurePath($parentPath)) {
|
||||||
|
$parentPath = './liste_albums';
|
||||||
|
}
|
||||||
|
?><!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?php echo htmlspecialchars($albumInfo['title']); ?> - ICO</title>
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body class="gallery-page">
|
||||||
|
<a href="albums.php?path=<?php echo urlencode($parentPath); ?>" class="back-button">Retour</a>
|
||||||
|
|
||||||
|
<?php if ($headerImage): ?>
|
||||||
|
<div class="gallery-header">
|
||||||
|
<img src="<?php echo htmlspecialchars($headerImage); ?>" alt="Image principale" class="header-image">
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="gallery-info">
|
||||||
|
<h1><?php echo htmlspecialchars($albumInfo['title']); ?></h1>
|
||||||
|
<?php if (!empty($albumInfo['description'])): ?>
|
||||||
|
<p><?php echo nl2br(htmlspecialchars($albumInfo['description'])); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="gallery-grid" id="gallery-grid">
|
||||||
|
<?php foreach($images as $image): ?>
|
||||||
|
<div class="gallery-item">
|
||||||
|
<a href="partage.php?image=<?php echo urlencode($image); ?>">
|
||||||
|
<img src="<?php echo htmlspecialchars($image); ?>" alt="Image de la galerie" loading="lazy">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const grid = document.querySelector('#gallery-grid');
|
||||||
|
const loadingClass = 'is-loading';
|
||||||
|
|
||||||
|
// Ajouter une classe de chargement
|
||||||
|
grid.classList.add(loadingClass);
|
||||||
|
|
||||||
|
// Initialiser Masonry avec imagesLoaded
|
||||||
|
imagesLoaded(grid, function() {
|
||||||
|
const masonry = new Masonry(grid, {
|
||||||
|
itemSelector: '.gallery-item',
|
||||||
|
columnWidth: '.gallery-item',
|
||||||
|
gutter: 20,
|
||||||
|
fitWidth: true,
|
||||||
|
transitionDuration: 0 // Désactiver l'animation pour le premier rendu
|
||||||
|
});
|
||||||
|
|
||||||
|
// Retirer la classe de chargement
|
||||||
|
grid.classList.remove(loadingClass);
|
||||||
|
|
||||||
|
// Réactiver les animations après le premier rendu
|
||||||
|
setTimeout(() => {
|
||||||
|
masonry.options.transitionDuration = '0.3s';
|
||||||
|
masonry.layout();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
79
index.php
Normal file
79
index.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
// Fonction pour récupérer les 5 dernières images
|
||||||
|
function getLatestImages($rootDir = './liste_albums', $limit = 5) {
|
||||||
|
$images = [];
|
||||||
|
$iterator = new RecursiveIteratorIterator(
|
||||||
|
new RecursiveDirectoryIterator($rootDir),
|
||||||
|
RecursiveIteratorIterator::SELF_FIRST
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($iterator as $file) {
|
||||||
|
if ($file->isFile()) {
|
||||||
|
$extension = strtolower($file->getExtension());
|
||||||
|
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||||
|
$images[] = str_replace('\\', '/', $file->getPathname());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($images, function($a, $b) {
|
||||||
|
return filectime($b) - filectime($a);
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_slice($images, 0, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
$latestImages = getLatestImages();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>ICO - Galerie d'images</title>
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="carousel">
|
||||||
|
<?php foreach($latestImages as $index => $image): ?>
|
||||||
|
<div class="carousel-slide <?php echo $index === 0 ? 'active' : ''; ?>">
|
||||||
|
<img src="<?php echo htmlspecialchars($image); ?>" alt="Image de la galerie">
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="overlay">
|
||||||
|
<h1>ICO</h1>
|
||||||
|
<p>ICO est la galerie d'images de l'association Camélia Studio.</p>
|
||||||
|
<a href="albums.php" class="cta-button">Accéder aux galeries</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
let currentSlide = 0;
|
||||||
|
const slides = document.querySelectorAll('.carousel-slide');
|
||||||
|
|
||||||
|
function showSlide(index) {
|
||||||
|
slides.forEach(slide => {
|
||||||
|
slide.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
slides[index].classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextSlide() {
|
||||||
|
currentSlide = (currentSlide + 1) % slides.length;
|
||||||
|
showSlide(currentSlide);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialiser le premier slide
|
||||||
|
showSlide(0);
|
||||||
|
|
||||||
|
// Changer de slide toutes les 5 secondes
|
||||||
|
setInterval(nextSlide, 5000);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
2
liste_albums/infos.txt
Normal file
2
liste_albums/infos.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Titre
|
||||||
|
Description sur la seconde ligne.
|
200
partage.php
Normal file
200
partage.php
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'fonctions.php';
|
||||||
|
|
||||||
|
// Vérifier que nous avons une URL d'image
|
||||||
|
$imageUrl = isset($_GET['image']) ? $_GET['image'] : null;
|
||||||
|
|
||||||
|
// Si pas d'image, redirection
|
||||||
|
if (!$imageUrl) {
|
||||||
|
header('Location: index.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupérer le nom du fichier pour le téléchargement
|
||||||
|
$filename = basename($imageUrl);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Image - ICO</title>
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body class="share-page">
|
||||||
|
<div class="share-container">
|
||||||
|
<div class="share-image">
|
||||||
|
<img src="<?php echo htmlspecialchars($imageUrl); ?>" alt="Image partagée">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="share-actions">
|
||||||
|
<button class="action-button" onclick="shareImage()">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"></path>
|
||||||
|
<polyline points="16 6 12 2 8 6"></polyline>
|
||||||
|
<line x1="12" y1="2" x2="12" y2="15"></line>
|
||||||
|
</svg>
|
||||||
|
Partager
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="action-button" onclick="embedImage()">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<polyline points="16 18 22 12 16 6"></polyline>
|
||||||
|
<polyline points="8 6 2 12 8 18"></polyline>
|
||||||
|
</svg>
|
||||||
|
Intégrer
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a href="<?php echo htmlspecialchars($imageUrl); ?>"
|
||||||
|
download="<?php echo htmlspecialchars($filename); ?>"
|
||||||
|
class="action-button">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
||||||
|
<polyline points="7 10 12 15 17 10"></polyline>
|
||||||
|
<line x1="12" y1="15" x2="12" y2="3"></line>
|
||||||
|
</svg>
|
||||||
|
Télécharger
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function copyToClipboard(text, button) {
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.value = text;
|
||||||
|
document.body.appendChild(input);
|
||||||
|
input.select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
document.body.removeChild(input);
|
||||||
|
|
||||||
|
// Sauvegarder l'HTML original
|
||||||
|
const originalHTML = button.innerHTML;
|
||||||
|
|
||||||
|
// Afficher la confirmation
|
||||||
|
button.innerHTML = `
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M20 6L9 17l-5-5"></path>
|
||||||
|
</svg>
|
||||||
|
Copié !
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Restaurer l'état original après 2 secondes
|
||||||
|
setTimeout(() => {
|
||||||
|
button.innerHTML = originalHTML;
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shareImage() {
|
||||||
|
copyToClipboard(window.location.href, document.querySelector('.action-button'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function embedImage() {
|
||||||
|
const imageUrl = '<?php echo htmlspecialchars($imageUrl); ?>';
|
||||||
|
copyToClipboard(imageUrl, document.querySelector('.action-button:nth-child(2)'));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html><?php
|
||||||
|
require_once 'functions.php';
|
||||||
|
|
||||||
|
// Vérifier que nous avons une URL d'image
|
||||||
|
$imageUrl = isset($_GET['image']) ? $_GET['image'] : null;
|
||||||
|
$returnUrl = isset($_GET['return']) ? $_GET['return'] : 'index.php';
|
||||||
|
|
||||||
|
// Si pas d'image, redirection
|
||||||
|
if (!$imageUrl) {
|
||||||
|
header('Location: ' . $returnUrl);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupérer le nom du fichier pour le téléchargement
|
||||||
|
$filename = basename($imageUrl);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Partager l'image - ICO</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body class="share-page">
|
||||||
|
<!-- Remplacer le lien de retour par un bouton -->
|
||||||
|
<button onclick="window.close();" class="back-button">Retour à la galerie</button>
|
||||||
|
|
||||||
|
<div class="share-container">
|
||||||
|
<div class="share-image">
|
||||||
|
<img src="<?php echo htmlspecialchars($imageUrl); ?>" alt="Image partagée">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="share-actions">
|
||||||
|
<button class="action-button" onclick="shareImage()">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"></path>
|
||||||
|
<polyline points="16 6 12 2 8 6"></polyline>
|
||||||
|
<line x1="12" y1="2" x2="12" y2="15"></line>
|
||||||
|
</svg>
|
||||||
|
Partager
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="action-button" onclick="embedImage()">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<polyline points="16 18 22 12 16 6"></polyline>
|
||||||
|
<polyline points="8 6 2 12 8 18"></polyline>
|
||||||
|
</svg>
|
||||||
|
Intégrer
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a href="<?php echo htmlspecialchars($imageUrl); ?>"
|
||||||
|
download="<?php echo htmlspecialchars($filename); ?>"
|
||||||
|
class="action-button">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
||||||
|
<polyline points="7 10 12 15 17 10"></polyline>
|
||||||
|
<line x1="12" y1="15" x2="12" y2="3"></line>
|
||||||
|
</svg>
|
||||||
|
Télécharger
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function copyToClipboard(text, button) {
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.value = text;
|
||||||
|
document.body.appendChild(input);
|
||||||
|
input.select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
document.body.removeChild(input);
|
||||||
|
|
||||||
|
// Sauvegarder l'HTML original
|
||||||
|
const originalHTML = button.innerHTML;
|
||||||
|
|
||||||
|
// Afficher la confirmation
|
||||||
|
button.innerHTML = `
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M20 6L9 17l-5-5"></path>
|
||||||
|
</svg>
|
||||||
|
Copié !
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Restaurer l'état original après 2 secondes
|
||||||
|
setTimeout(() => {
|
||||||
|
button.innerHTML = originalHTML;
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shareImage() {
|
||||||
|
copyToClipboard(window.location.href, document.querySelector('.action-button'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function embedImage() {
|
||||||
|
const imageUrl = '<?php echo htmlspecialchars($imageUrl); ?>';
|
||||||
|
copyToClipboard(imageUrl, document.querySelector('.action-button:nth-child(2)'));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
460
styles.css
Normal file
460
styles.css
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
/* Accessibilité */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
* {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
}/* Reset et styles de base */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', system-ui, sans-serif;
|
||||||
|
background-color: #121212;
|
||||||
|
color: #ffffff;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styles de la page d'accueil */
|
||||||
|
.carousel {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-slide {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 1s ease-in-out;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-slide.active {
|
||||||
|
opacity: 1;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-slide img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: cover;
|
||||||
|
filter: brightness(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overlay contenu */
|
||||||
|
.overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
z-index: 20;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 600px;
|
||||||
|
padding: 2rem;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
border-radius: 1rem;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 4rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
background-color: #2196f3;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 2rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button:hover {
|
||||||
|
background-color: #1976d2;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styles pour la page des albums */
|
||||||
|
.albums-page {
|
||||||
|
background-color: #121212;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 2rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.albums-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||||
|
gap: 2rem;
|
||||||
|
max-width: 1800px;
|
||||||
|
margin: 4rem auto 2rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-card {
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
border-radius: 1rem;
|
||||||
|
overflow: hidden;
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
transition: opacity 0.5s ease, transform 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-card.visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-images {
|
||||||
|
position: relative;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-template-rows: repeat(2, 1fr);
|
||||||
|
aspect-ratio: 1;
|
||||||
|
gap: 2px;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-album {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
grid-row: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-info {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-info h2 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styles pour la page galerie */
|
||||||
|
.gallery-page {
|
||||||
|
background-color: #121212;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-header {
|
||||||
|
width: 100%;
|
||||||
|
height: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-info {
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 1800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-grid {
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 1800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-grid.is-loading .gallery-item {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-grid .gallery-item {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item {
|
||||||
|
width: calc((100% - (7 * 20px)) / 8);
|
||||||
|
min-width: 200px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
min-height: 150px;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bouton retour commun */
|
||||||
|
.back-button {
|
||||||
|
position: fixed;
|
||||||
|
top: 2rem;
|
||||||
|
left: 2rem;
|
||||||
|
padding: 0.8rem 1.5rem;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 2rem;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
z-index: 100;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.9);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Media Queries */
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
.albums-grid {
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1600px) {
|
||||||
|
.gallery-item {
|
||||||
|
width: calc((100% - (5 * 20px)) / 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.albums-grid {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
}
|
||||||
|
.gallery-item {
|
||||||
|
width: calc((100% - (3 * 20px)) / 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 992px) {
|
||||||
|
.albums-grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
.gallery-item {
|
||||||
|
width: calc((100% - (3 * 20px)) / 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.albums-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.albums-page {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item {
|
||||||
|
width: calc((100% - (2 * 20px)) / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-header {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-info {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-info h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
padding: 0.8rem 1.6rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.albums-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item {
|
||||||
|
width: calc((100% - 20px) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-grid {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-header {
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button {
|
||||||
|
top: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
padding: 0.6rem 1.2rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-page {
|
||||||
|
background-color: rgba(0, 0, 0, 0.9);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-container {
|
||||||
|
max-width: 90vw;
|
||||||
|
max-height: 90vh;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-image {
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-image img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 90vh;
|
||||||
|
display: block;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-actions {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 2rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajuster .action-button pour la page de partage */
|
||||||
|
.share-actions .action-button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.8rem 1.5rem;
|
||||||
|
background-color: #2196f3;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-actions .action-button:hover {
|
||||||
|
background-color: #1976d2;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-actions .action-button .icon {
|
||||||
|
width: 1.2em;
|
||||||
|
height: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Protection par mot de passe */
|
||||||
|
.protected-indicator {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
font-size: 0.8em;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Media queries pour la page de partage */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.share-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-actions .action-button {
|
||||||
|
padding: 0.6rem 1.2rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
* {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user