diff --git a/.env.model b/.env.model index b9b94ed..141ab24 100755 --- a/.env.model +++ b/.env.model @@ -39,6 +39,7 @@ TEST_POSTGRES_PASSWORD=test_pass #STORAGE_TYPE=oci STORAGE_TYPE=local STORAGE_ROOT=/var/www/html/storage +SHARE_BASE_URL= # --- Oracle Cloud Object Storage --- OCI_USER_OCID= diff --git a/Jenkinsfile b/Jenkinsfile index c48a068..e70e5e6 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -73,6 +73,7 @@ pipeline { echo "OCI_REGION=${OCI_REGION}" >> .env echo "OCI_NAMESPACE=${OCI_NAMESPACE}" >> .env echo "OCI_BUCKET=${OCI_BUCKET}" >> .env + echo "SHARE_BASE_URL=https://server1.fabriciolr.online:1234" >> .env """ sh ''' diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf index 18dd9c2..1391aa0 100755 --- a/docker/nginx/default.conf +++ b/docker/nginx/default.conf @@ -23,6 +23,11 @@ server { return 404; } + # Friendly share URLs (UUID v4) + location ~ "^/([0-9a-f\-]{36})$" { + rewrite ^/(.*)$ /s.php?uuid=$1 last; + } + # Redireciona tudo que não existe para o index.php (caso usassemos rotas, mas será padrão) location / { try_files $uri $uri/ /index.php?$query_string; diff --git a/docker/nginx/prod.conf b/docker/nginx/prod.conf index 0a5b855..6ef2a76 100755 --- a/docker/nginx/prod.conf +++ b/docker/nginx/prod.conf @@ -27,6 +27,11 @@ server { return 404; } + # Friendly share URLs (UUID v4) + location ~ "^/([0-9a-f\-]{36})$" { + rewrite ^/(.*)$ /s.php?uuid=$1 last; + } + # Redireciona tudo que não existe para o index.php (caso usassemos rotas, mas será padrão) location / { try_files $uri $uri/ /index.php?$query_string; diff --git a/public/css/dashboard.css b/public/css/dashboard.css index 90ed338..f557676 100755 --- a/public/css/dashboard.css +++ b/public/css/dashboard.css @@ -116,3 +116,143 @@ margin-top: 0.5rem; } } + +/* Share Button */ +.action-btn-share { + display: none; background: rgba(0,0,0,0.05); color: var(--text-main); padding: 0.4rem 0.8rem; +} + +/* Modal */ +.modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0,0,0,0.6); + backdrop-filter: blur(12px); + opacity: 0; + transition: opacity 0.3s ease; +} + +.modal.active { + display: block; + opacity: 1; +} + +.share-modal-content { + max-width: 480px; + margin: 8% auto; + padding: 2.5rem; + position: relative; + border-radius: 24px; + border: 1px solid rgba(255, 255, 255, 0.15); + background: rgba(18, 18, 24, 0.85); + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6); +} + +.share-file-name { + margin-bottom: 2rem; + color: var(--text-muted); + font-size: 0.95rem; + padding: 0.75rem 1rem; + background: rgba(255, 255, 255, 0.03); + border-radius: 12px; + border-left: 3px solid var(--primary-color); +} + +.share-form-group label { + display: block; + margin-bottom: 0.75rem; + font-weight: 500; +} + +.share-select { + width: 100%; + padding: 0.8rem 1rem; + border-radius: 12px; + background: rgba(255, 255, 255, 0.05); + color: white; + border: 1px solid rgba(255, 255, 255, 0.1); + font-size: 1rem; + outline: none; + cursor: pointer; + transition: all 0.3s ease; + appearance: none; +} + +.share-select:focus { + border-color: var(--primary-color); + background: rgba(255, 255, 255, 0.1); +} + +.share-select option { + background-color: #1a1a24; + color: white; +} + +.share-result-area { + display: none; + margin-top: 2rem; + animation: slideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1); +} + +@keyframes slideUp { + from { opacity: 0; transform: translateY(15px); } + to { opacity: 1; transform: translateY(0); } +} + +.share-link-box { + display: flex; + gap: 0.5rem; + margin-top: 0.75rem; + background: rgba(0, 0, 0, 0.3); + padding: 0.4rem; + border-radius: 14px; + border: 1px solid rgba(255, 255, 255, 0.08); + align-items: center; +} + +.share-link-box input { + flex: 1; + background: transparent; + border: none; + color: #fff; + padding: 0.6rem 0.8rem; + font-family: monospace; + font-size: 0.85rem; + outline: none; +} + +.btn-copy { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.6rem 1rem; + border-radius: 10px; + font-size: 0.9rem; +} + +.share-modal-actions { + margin-top: 2.5rem; + display: flex; + justify-content: flex-end; + gap: 1rem; +} + +.shadow-glow { + box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4); +} + +.btn-secondary { + background: rgba(255, 255, 255, 0.05); + color: white; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.btn-secondary:hover { + background: rgba(255, 255, 255, 0.1); +} diff --git a/public/css/style.css b/public/css/style.css index 1778473..fa6773a 100755 --- a/public/css/style.css +++ b/public/css/style.css @@ -315,7 +315,7 @@ select:focus { background: #ffffff; border: 1px solid var(--border); border-radius: 8px; - width: 180px; + width: 220px; display: none; flex-direction: column; z-index: 9999; diff --git a/public/dashboard.php b/public/dashboard.php index 27a136e..6c3e0e4 100755 --- a/public/dashboard.php +++ b/public/dashboard.php @@ -151,6 +151,8 @@ function formatBytes($bytes, $precision = 2) { $bytes /= pow(1024, $pow); return round($bytes, $precision) . ' ' . $units[$pow]; } + +$shareBaseUrl = getenv('SHARE_BASE_URL') ?: ''; ?> @@ -160,6 +162,9 @@ function formatBytes($bytes, $precision = 2) {