diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..a968d6d
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,60 @@
+# Empêcher l'accès direct aux fichiers PHP
+
+
+ Order Allow,Deny
+ Deny from all
+
+
+ Require all denied
+
+
+
+
+ Order Allow,Deny
+ Allow from all
+
+
+ Require all granted
+
+
+# Autoriser l'accès aux points d'entrée spécifiques
+
+
+ Order Allow,Deny
+ Allow from all
+
+
+ Require all granted
+
+
+
+# Définir les types MIME corrects
+AddType text/css .css
+AddType application/javascript .js
+AddType image/x-icon .ico
+AddType image/svg+xml .svg
+AddType application/x-font-woff .woff
+AddType application/x-font-woff2 .woff2
+
+# Activer la compression
+
+ AddOutputFilterByType DEFLATE text/plain
+ AddOutputFilterByType DEFLATE text/html
+ AddOutputFilterByType DEFLATE text/css
+ AddOutputFilterByType DEFLATE application/javascript
+ AddOutputFilterByType DEFLATE application/x-javascript
+ AddOutputFilterByType DEFLATE text/javascript
+
+
+# Cache headers
+
+ ExpiresActive On
+ ExpiresDefault "access plus 1 month"
+
+ ExpiresByType text/css "access plus 1 year"
+ ExpiresByType application/javascript "access plus 1 year"
+ ExpiresByType image/x-icon "access plus 1 year"
+
+
+# Protection des dossiers
+Options -Indexes
\ No newline at end of file
diff --git a/admin.php b/admin.php
new file mode 100644
index 0000000..672bfbd
--- /dev/null
+++ b/admin.php
@@ -0,0 +1,368 @@
+ \'' . preg_quote($user['password'], '/') . '\'/',
+ '\'password\' => \'' . $ADMIN_USERS[$username]['password'] . '\'',
+ $config_content
+ );
+ file_put_contents('config.php', $config_content);
+
+ $success = 'Mot de passe modifié avec succès';
+ }
+ }
+ }
+}
+
+// Traitement de l'upload de fichier
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upload') {
+ if (!isset($_POST['csrf_token']) || !Cyla::verifyCSRFToken($_POST['csrf_token'])) {
+ $error = 'Token de sécurité invalide';
+ } else if (!isset($_FILES['file'])) {
+ $error = 'Aucun fichier n\'a été envoyé';
+ } else {
+ $validation = Cyla::validateUpload($_FILES['file']);
+
+ if (!$validation['valid']) {
+ $error = $validation['error'];
+ } else {
+ $filename = Cyla::generateUniqueFilename($_FILES['file']['name']);
+ $destination = UPLOAD_DIR . $filename;
+
+ if (move_uploaded_file($_FILES['file']['tmp_name'], $destination)) {
+ $success = 'Fichier uploadé avec succès';
+ } else {
+ $error = 'Erreur lors de l\'upload du fichier';
+ }
+ }
+ }
+}
+
+// Liste des fichiers
+$files = Cyla::listFiles();
+
+// Contenu de la page
+$pageTitle = 'Administration';
+ob_start(); ?>
+
+
+
+
Téléversement de fichier
+
+
+
+
+
+
+ Glissez-déposez vos fichiers ici
+ ou cliquez pour sélectionner
+
+
+ Taille maximale : 100 Mo
+ Extensions :
+
+
+
+
+
+
+
+
+
+
+
Changer le mot de passe
+
+
+
+
+
Fichiers hébergés
+
+
Aucun fichier hébergé
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ko
+ ·
+
+
+
Voir
+
Copier le lien
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'Non autorisé']);
+ exit;
+}
+
+// Vérifier le token CSRF
+if (!isset($_POST['csrf_token']) || !Cyla::verifyCSRFToken($_POST['csrf_token'])) {
+ http_response_code(403);
+ echo json_encode(['error' => 'Token CSRF invalide']);
+ exit;
+}
+
+// Gérer l'upload de fichier
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
+ $validation = Cyla::validateUpload($_FILES['file']);
+
+ if (!$validation['valid']) {
+ http_response_code(400);
+ echo json_encode(['error' => $validation['error']]);
+ exit;
+ }
+
+ $filename = Cyla::generateUniqueFilename($_FILES['file']['name']);
+ $destination = UPLOAD_DIR . $filename;
+
+ if (move_uploaded_file($_FILES['file']['tmp_name'], $destination)) {
+ echo json_encode([
+ 'success' => true,
+ 'file' => [
+ 'name' => $filename,
+ 'size' => filesize($destination),
+ 'url' => 'share.php?file=' . urlencode($filename)
+ ]
+ ]);
+ } else {
+ http_response_code(500);
+ echo json_encode(['error' => 'Erreur lors de l\'upload du fichier']);
+ }
+ exit;
+}
+
+// Méthode non autorisée
+http_response_code(405);
+echo json_encode(['error' => 'Méthode non autorisée']);
\ No newline at end of file
diff --git a/config.php b/config.php
new file mode 100644
index 0000000..5cbc397
--- /dev/null
+++ b/config.php
@@ -0,0 +1,76 @@
+ ['password' => 'hashed_password', 'salt' => 'random_salt'])
+$ADMIN_USERS = [
+ 'admin' => [
+ 'password' => 'a94637ad7685d8a3e64c97eddd7751a0ff55434a607361b7304edf41b39ab7f8', // Default: 'password'
+ 'salt' => 'defaultsalt123'
+ ]
+];
+
+// Session configuration
+define('SESSION_LIFETIME', 3600); // Durée de vie de la session en secondes (1 heure)
+define('SESSION_NAME', 'CYLA_SESSION');
+
+// Error reporting
+define('DEBUG_MODE', false); // À mettre à false en production
+if (DEBUG_MODE) {
+ error_reporting(E_ALL);
+ ini_set('display_errors', 1);
+} else {
+ error_reporting(0);
+ ini_set('display_errors', 0);
+}
+
+// Fonction pour vérifier si une extension est autorisée
+function isAllowedExtension($extension) {
+ return in_array(strtolower($extension), ALLOWED_EXTENSIONS);
+}
+
+// Fonction pour vérifier si un fichier peut avoir un aperçu
+function canPreview($extension) {
+ $extension = strtolower($extension);
+ return in_array($extension, PREVIEW_IMAGES) ||
+ in_array($extension, PREVIEW_VIDEOS) ||
+ in_array($extension, PREVIEW_AUDIOS) ||
+ in_array($extension, PREVIEW_TEXTS);
+}
+
+// Fonction pour obtenir le type d'aperçu
+function getPreviewType($extension) {
+ $extension = strtolower($extension);
+ if (in_array($extension, PREVIEW_IMAGES)) return 'image';
+ if (in_array($extension, PREVIEW_VIDEOS)) return 'video';
+ if (in_array($extension, PREVIEW_AUDIOS)) return 'audio';
+ if (in_array($extension, PREVIEW_TEXTS)) return 'text';
+ return 'none';
+}
\ No newline at end of file
diff --git a/core.php b/core.php
new file mode 100644
index 0000000..ba1ec29
--- /dev/null
+++ b/core.php
@@ -0,0 +1,156 @@
+ bool, 'error' => string|null]
+ */
+ public static function validateUpload($file) {
+ $result = ['valid' => true, 'error' => null];
+
+ // Vérifier les erreurs d'upload PHP
+ if ($file['error'] !== UPLOAD_ERR_OK) {
+ $result['valid'] = false;
+ $result['error'] = 'Erreur lors de l\'upload';
+ return $result;
+ }
+
+ // Vérifier la taille
+ if ($file['size'] > MAX_FILE_SIZE) {
+ $result['valid'] = false;
+ $result['error'] = 'Le fichier dépasse la taille maximale autorisée';
+ return $result;
+ }
+
+ // Vérifier l'extension
+ $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
+ if (!isAllowedExtension($extension)) {
+ $result['valid'] = false;
+ $result['error'] = 'Extension de fichier non autorisée';
+ return $result;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Sécurise les sorties HTML
+ * @param string $text Texte à sécuriser
+ * @return string
+ */
+ public static function escape($text) {
+ return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
+ }
+
+ /**
+ * Génère un token CSRF
+ * @return string
+ */
+ public static function generateCSRFToken() {
+ if (!isset($_SESSION['csrf_token'])) {
+ $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
+ }
+ return $_SESSION['csrf_token'];
+ }
+
+ /**
+ * Vérifie un token CSRF
+ * @param string $token Token à vérifier
+ * @return bool
+ */
+ public static function verifyCSRFToken($token) {
+ return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
+ }
+
+ /**
+ * Liste les fichiers uploadés
+ * @return array
+ */
+ public static function listFiles() {
+ $files = [];
+ foreach (glob(UPLOAD_DIR . '*') as $file) {
+ $info = pathinfo($file);
+ $files[] = [
+ 'name' => basename($file),
+ 'size' => filesize($file),
+ 'extension' => strtolower($info['extension']),
+ 'uploaded' => filemtime($file),
+ 'preview_type' => getPreviewType($info['extension'])
+ ];
+ }
+ return $files;
+ }
+}
+
+// Vérifier et mettre à jour l'activité si l'utilisateur est connecté
+if (Cyla::isLoggedIn()) {
+ Cyla::updateActivity();
+}
\ No newline at end of file
diff --git a/css/style.css b/css/style.css
new file mode 100644
index 0000000..1360ccd
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,345 @@
+/* Variables */
+:root {
+ /* Couleurs principales */
+ --color-bg: #1a1716;
+ --color-bg-alt: #231f1d;
+ --color-text: #e6d5c5;
+ --color-text-muted: #a18d7a;
+ --color-primary: #d4846a;
+ --color-primary-hover: #e6977c;
+ --color-accent: #8b4b45;
+ --color-border: #382f2a;
+
+ /* Alertes */
+ --color-error: #ff6b6b;
+ --color-success: #51cf66;
+
+ /* Espacements */
+ --spacing-xs: 0.25rem;
+ --spacing-sm: 0.5rem;
+ --spacing-md: 1rem;
+ --spacing-lg: 2rem;
+
+ /* Bordures */
+ --border-radius: 4px;
+}
+
+/* Reset et base */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: 1.6;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+/* Navigation */
+header {
+ background-color: var(--color-bg-alt);
+ border-bottom: 1px solid var(--color-border);
+ padding: var(--spacing-md) var(--spacing-lg);
+}
+
+nav {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ max-width: 1200px;
+ margin: 0 auto;
+ width: 100%;
+}
+
+.nav-brand a {
+ color: var(--color-primary);
+ font-size: 1.5rem;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+.nav-menu {
+ display: flex;
+ gap: var(--spacing-md);
+}
+
+.nav-link {
+ color: var(--color-text);
+ text-decoration: none;
+ padding: var(--spacing-sm) var(--spacing-md);
+ border-radius: var(--border-radius);
+ transition: background-color 0.3s ease;
+}
+
+.nav-link:hover {
+ background-color: var(--color-border);
+}
+
+/* Main content */
+main {
+ flex: 1;
+ padding: var(--spacing-lg);
+ max-width: 1200px;
+ margin: 0 auto;
+ width: 100%;
+}
+
+/* Cards */
+.card {
+ background-color: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: var(--border-radius);
+ padding: var(--spacing-lg);
+ margin-bottom: var(--spacing-lg);
+}
+
+/* Forms */
+.form-group {
+ margin-bottom: var(--spacing-md);
+}
+
+label {
+ display: block;
+ margin-bottom: var(--spacing-xs);
+ color: var(--color-text-muted);
+}
+
+input[type="text"],
+input[type="password"],
+textarea {
+ width: 100%;
+ padding: var(--spacing-sm);
+ background-color: var(--color-bg);
+ border: 1px solid var(--color-border);
+ border-radius: var(--border-radius);
+ color: var(--color-text);
+}
+
+input[type="text"]:focus,
+input[type="password"]:focus,
+textarea:focus {
+ outline: none;
+ border-color: var(--color-primary);
+}
+
+/* Buttons */
+.btn {
+ display: inline-block;
+ padding: var(--spacing-sm) var(--spacing-md);
+ background-color: var(--color-primary);
+ color: var(--color-text);
+ border: none;
+ border-radius: var(--border-radius);
+ cursor: pointer;
+ text-decoration: none;
+ transition: background-color 0.3s ease;
+}
+
+.btn:hover {
+ background-color: var(--color-primary-hover);
+}
+
+.btn-secondary {
+ background-color: var(--color-border);
+}
+
+.btn-secondary:hover {
+ background-color: var(--color-text-muted);
+}
+
+/* Alerts */
+.alert {
+ padding: var(--spacing-md);
+ border-radius: var(--border-radius);
+ margin-bottom: var(--spacing-md);
+}
+
+.alert-error {
+ background-color: var(--color-error);
+ color: white;
+}
+
+.alert-success {
+ background-color: var(--color-success);
+ color: white;
+}
+
+/* File list */
+.file-list {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+ gap: var(--spacing-md);
+}
+
+.file-item {
+ background-color: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: var(--border-radius);
+ padding: var(--spacing-md);
+}
+
+.file-preview {
+ aspect-ratio: 16/9;
+ background-color: var(--color-bg);
+ border-radius: var(--border-radius);
+ margin-bottom: var(--spacing-sm);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+}
+
+.file-preview img,
+.file-preview video {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+}
+
+.file-info {
+ color: var(--color-text-muted);
+ font-size: 0.9rem;
+}
+
+/* Footer */
+footer {
+ background-color: var(--color-bg-alt);
+ border-top: 1px solid var(--color-border);
+ padding: var(--spacing-lg);
+ text-align: center;
+ color: var(--color-text-muted);
+}
+
+/* Zone d'upload */
+.upload-zone {
+ position: relative;
+ border: 2px dashed var(--color-border);
+ border-radius: var(--border-radius);
+ padding: 2rem;
+ text-align: center;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.upload-zone:hover {
+ border-color: var(--color-primary);
+}
+
+.upload-zone-active {
+ border-color: var(--color-primary);
+ background-color: rgba(212, 132, 106, 0.1);
+}
+
+.file-input {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ opacity: 0;
+ cursor: pointer;
+}
+
+.upload-content {
+ pointer-events: none;
+}
+
+.upload-icon {
+ margin-bottom: 1rem;
+}
+
+.upload-icon svg {
+ stroke: var(--color-text-muted);
+ margin: 0 auto;
+}
+
+.upload-text {
+ margin-bottom: 0.5rem;
+ color: var(--color-text);
+}
+
+.upload-text-sub {
+ font-size: 0.9em;
+ color: var(--color-text-muted);
+}
+
+.upload-limit {
+ font-size: 0.8em;
+ color: var(--color-text-muted);
+}
+
+/* Liste des fichiers */
+.file-list {
+ margin-top: 1rem;
+}
+
+.file-item {
+ background: var(--color-bg-alt);
+ border: 1px solid var(--color-border);
+ border-radius: var(--border-radius);
+ padding: 1rem;
+ margin-bottom: 0.5rem;
+}
+
+.file-item-content {
+ display: grid;
+ gap: 0.5rem;
+}
+
+.file-item-name {
+ font-weight: 500;
+ word-break: break-all;
+}
+
+.file-item-size {
+ color: var(--color-text-muted);
+ font-size: 0.9em;
+}
+
+.file-item-progress {
+ height: 4px;
+ background: var(--color-border);
+ border-radius: 2px;
+ overflow: hidden;
+}
+
+.progress-bar {
+ height: 100%;
+ background: var(--color-primary);
+ width: 0;
+ transition: width 0.3s ease;
+}
+
+.file-item-error {
+ border-color: var(--color-error);
+}
+
+.file-item-error .file-item-error-message {
+ color: var(--color-error);
+ font-size: 0.9em;
+}
+
+.file-item-success {
+ border-color: var(--color-success);
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ .nav-menu {
+ display: none;
+ }
+
+ main {
+ padding: var(--spacing-md);
+ }
+
+ .file-list {
+ grid-template-columns: 1fr;
+ }
+}
\ No newline at end of file
diff --git a/cyla2api.php b/cyla2api.php
deleted file mode 100644
index d09b2cb..0000000
--- a/cyla2api.php
+++ /dev/null
@@ -1,32 +0,0 @@
-'; // URL to shrink
-$format = 'simple'; // output format: 'json', 'xml' or 'simple'
-
-// EDIT THIS: the URL of the API file
-$api_url = 'http://ersatz.xyz/yourls-api.php';
-
-// Init the CURL session
-$ch = curl_init();
-curl_setopt( $ch, CURLOPT_URL, $api_url );
-curl_setopt( $ch, CURLOPT_HEADER, 0 ); // No header in the result
-curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // Return, do not echo result
-curl_setopt( $ch, CURLOPT_POST, 1 ); // This is a POST request
-curl_setopt( $ch, CURLOPT_POSTFIELDS, array( // Data to POST
- 'url' => $url,
- 'format' => $format,
- 'action' => 'shorturl',
- 'signature' => $signature,
- ) );
-
-// Fetch and return content
-$data = curl_exec($ch);
-curl_close($ch);
-
-// Do something with the result. Here, we just echo it.
-echo $data;
-
diff --git a/file/fichiers_ici.md b/file/fichiers_ici.md
deleted file mode 100644
index 72f1cc7..0000000
--- a/file/fichiers_ici.md
+++ /dev/null
@@ -1 +0,0 @@
-Les fichiers seront stockés dans ce dossier.
\ No newline at end of file
diff --git a/gallery.php b/gallery.php
deleted file mode 100644
index 5d1a5fe..0000000
--- a/gallery.php
+++ /dev/null
@@ -1,311 +0,0 @@
- $file,
- 'url' => 'file/' . rawurlencode($file),
- 'shareUrl' => 'share/' . rawurlencode($file),
- 'date' => filemtime($path),
- 'type' => strtolower(pathinfo($file, PATHINFO_EXTENSION))
- ];
- }
- }
-
- // Tri
- usort($files, function($a, $b) use ($sortBy, $sortDesc) {
- $result = $sortBy === 'date'
- ? $b['date'] - $a['date']
- : strcasecmp($a['name'], $b['name']);
- return $sortDesc ? $result : -$result;
- });
-
- // Pagination
- $offset = $page * FILES_PER_PAGE;
- return array_slice($files, $offset, FILES_PER_PAGE);
-}
-
-if (!$authenticated) {
- // Afficher le formulaire de connexion
- include 'header.php';
- ?>
-
-
-
-
-
-
- Galerie de fichiers
-
-
-
-
-
- Date = $sortBy === 'date' ? ($sortDesc ? '↓' : '↑') : '' ?>
-
-
- Nom = $sortBy === 'name' ? ($sortDesc ? '↓' : '↑') : '' ?>
-
-
-
-
-
- Chargement...
-
-
-
-
diff --git a/index.php b/index.php
deleted file mode 100644
index f213b32..0000000
--- a/index.php
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
- Cyla - hébergement de fichiers
-
-
-
-
-
-
-
-
-
-
- Cyla
-
-
-
- Un fichier ne peut dépasser 100 Mo. Les extensions autorisées sont 'png', 'jpg', 'jpeg', 'gif', 'webm', 'mp4', 'wmv', 'mp3', 'flac', 'ogg', 'zip', 'css', 'pdf', 'zip', 'rar', 'm3u', 'm3u8', 'txt'.
-
-
-
-
-
-
- En utilisant ce service, vous acceptez les limites situées à la page info .
-
-
-
-
-
-
-
diff --git a/js/UploadZone.jsx b/js/UploadZone.jsx
new file mode 100644
index 0000000..4da6030
--- /dev/null
+++ b/js/UploadZone.jsx
@@ -0,0 +1,207 @@
+import React, { useState, useRef } from 'react';
+import { X, Upload, CheckCircle, AlertCircle } from 'lucide-react';
+
+const UploadZone = () => {
+ const [isDragging, setIsDragging] = useState(false);
+ const [files, setFiles] = useState([]);
+ const fileInputRef = useRef(null);
+
+ const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 Mo
+ const ALLOWED_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webm', 'mp4', 'wmv', 'mp3', 'flac', 'ogg', 'zip', 'css', 'pdf', 'rar', 'm3u', 'm3u8', 'txt'];
+
+ const handleDragOver = (e) => {
+ e.preventDefault();
+ setIsDragging(true);
+ };
+
+ const handleDragLeave = (e) => {
+ e.preventDefault();
+ setIsDragging(false);
+ };
+
+ const validateFile = (file) => {
+ const extension = file.name.split('.').pop().toLowerCase();
+ if (!ALLOWED_EXTENSIONS.includes(extension)) {
+ return { valid: false, error: `Extension .${extension} non autorisée` };
+ }
+ if (file.size > MAX_FILE_SIZE) {
+ return { valid: false, error: 'Fichier trop volumineux (max 100 Mo)' };
+ }
+ return { valid: true, error: null };
+ };
+
+ const handleDrop = (e) => {
+ e.preventDefault();
+ setIsDragging(false);
+
+ const droppedFiles = Array.from(e.dataTransfer.files);
+ addFiles(droppedFiles);
+ };
+
+ const handleFileSelect = (e) => {
+ const selectedFiles = Array.from(e.target.files);
+ addFiles(selectedFiles);
+ };
+
+ const addFiles = (newFiles) => {
+ const processedFiles = newFiles.map(file => {
+ const validation = validateFile(file);
+ return {
+ file,
+ id: Math.random().toString(36).substring(7),
+ status: validation.valid ? 'pending' : 'error',
+ error: validation.error,
+ progress: 0
+ };
+ });
+
+ setFiles(currentFiles => [...currentFiles, ...processedFiles]);
+ };
+
+ const removeFile = (fileId) => {
+ setFiles(files => files.filter(f => f.id !== fileId));
+ };
+
+ const uploadFile = async (fileInfo) => {
+ const formData = new FormData();
+ formData.append('file', fileInfo.file);
+ formData.append('action', 'upload');
+
+ try {
+ // Simuler un upload progressif pour la démo
+ await new Promise(resolve => {
+ let progress = 0;
+ const interval = setInterval(() => {
+ progress += 10;
+ setFiles(files =>
+ files.map(f =>
+ f.id === fileInfo.id
+ ? { ...f, progress, status: progress === 100 ? 'complete' : 'uploading' }
+ : f
+ )
+ );
+ if (progress >= 100) {
+ clearInterval(interval);
+ resolve();
+ }
+ }, 500);
+ });
+ } catch (error) {
+ setFiles(files =>
+ files.map(f =>
+ f.id === fileInfo.id
+ ? { ...f, status: 'error', error: 'Erreur lors du téléversement' }
+ : f
+ )
+ );
+ }
+ };
+
+ const uploadAllFiles = () => {
+ const pendingFiles = files.filter(f => f.status === 'pending');
+ pendingFiles.forEach(uploadFile);
+ };
+
+ const getStatusColor = (status) => {
+ switch (status) {
+ case 'complete': return 'text-green-500';
+ case 'error': return 'text-red-500';
+ case 'uploading': return 'text-blue-500';
+ default: return 'text-gray-500';
+ }
+ };
+
+ const getStatusIcon = (status) => {
+ switch (status) {
+ case 'complete': return ;
+ case 'error': return ;
+ default: return null;
+ }
+ };
+
+ return (
+
+
fileInputRef.current?.click()}
+ >
+
`.${ext}`).join(',')}
+ />
+
+
+
+ Glissez-déposez vos fichiers ici
+
+
+ ou cliquez pour sélectionner des fichiers
+
+
+ Max 100 Mo par fichier · {ALLOWED_EXTENSIONS.join(', ')}
+
+
+
+ {files.length > 0 && (
+
+
+
Files ({files.length})
+
+ Tout téléverser
+
+
+
+
+ {files.map((fileInfo) => (
+
+
+
{fileInfo.file.name}
+
+ {(fileInfo.file.size / 1024 / 1024).toFixed(2)} Mo
+
+ {fileInfo.error && (
+
{fileInfo.error}
+ )}
+
+
+ {fileInfo.status === 'uploading' && (
+
+ )}
+
+
+ {getStatusIcon(fileInfo.status)}
+
+
+
removeFile(fileInfo.id)}
+ className="p-1 hover:bg-gray-700 rounded"
+ >
+
+
+
+ ))}
+
+
+ )}
+
+ );
+};
+
+export default UploadZone;
\ No newline at end of file
diff --git a/js/main.js b/js/main.js
new file mode 100644
index 0000000..eb0d5d4
--- /dev/null
+++ b/js/main.js
@@ -0,0 +1,21 @@
+// Fonction pour copier dans le presse-papier
+function copyToClipboard(text) {
+ navigator.clipboard.writeText(text).then(() => {
+ alert('Copié dans le presse-papier !');
+ }).catch(err => {
+ console.error('Erreur lors de la copie :', err);
+ alert('Erreur lors de la copie');
+ });
+}
+
+// Fonction pour prévisualiser un fichier avant l'upload
+function previewFile(input) {
+ if (input.files && input.files[0]) {
+ const file = input.files[0];
+ const fileSize = (file.size / 1024 / 1024).toFixed(2); // Taille en Mo
+
+ // Afficher les informations du fichier
+ document.getElementById('fileInfo').textContent =
+ `${file.name} (${fileSize} Mo)`;
+ }
+}
\ No newline at end of file
diff --git a/layout.php b/layout.php
new file mode 100644
index 0000000..188722a
--- /dev/null
+++ b/layout.php
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/login.php b/login.php
new file mode 100644
index 0000000..23db768
--- /dev/null
+++ b/login.php
@@ -0,0 +1,108 @@
+
+
+
+
Connexion à l'administration
+
+
+
+
+
+
+
-
- Cyla faq
-
-
-
-
-
-Questions fréquemment posées
-
-Je n'accepte pas d'autres types de fichiers car ils ne sont pas optimisés pour le web. (En fait, tous les fichiers MP4 ne le sont pas).
-Si vous voulez convertir des vidéos au format WebM (format recommandé) pour le téléchargement, télécharger la dernière version de convertisseur de WebM de 4chan's .
-Vous regardez tous les fichiers que j'héberge ?
-Non, je ne regarde pas en détail tous les fichiers hébergés. Je peux cependant y jeter un œil, notamment pour vérifier qu'il n'y a pas de virus par exemple.
-En tout cas, je ne partagerais jamais un fichier que je n'ai pas moi-même hébergé.
-Cyla est lent, que se passe-t-il ?
-Il est probable que le serveur soit sous une lourde charge (par exemple si un trop grand nombre de personnes envoient des fichiers en même temps). Si cela arrive, essayez plus tard.
-Le serveur utilisé n'est pas optimisé pour cela à la base.
-Quelle est la place de stockage disponible ?
-Cela peut évoluer avec le temps suivant les besoins.
-Qu'arriverait-il si Cyla grandi delà de ce que vous pouvez vous permettre de maintenir ?
-S'il commence à manquer de place et que je n'ai pas les moyens d'en acheter plus, il est possible que le poids pour l'envoie d'un fichier soit réduit (passer de 100 Mo à 50 Mo (ou moins) par exemple).
-Si vous voulez me permettre d'avoir un serveur plus performant et disposant de plus d'espace, vous pouvez me faire un don sur Paypal .
-En dernier recours, il est possible que l'envoie de fichiers soit arrêté. Les fichiers déjà hébergés resteraient toutefois toujours disponible.
-
-Retour à l'accueil
-
-
-