master #1

Closed
admin wants to merge 19 commits from master into main
Showing only changes of commit 05c2b86144 - Show all commits
+35 -8
View File
@@ -26,10 +26,18 @@ body{font-family:'Segoe UI',system-ui,-apple-system,Roboto,sans-serif;background
.card .name{font-size:1.02rem;font-weight:700;color:var(--dark);letter-spacing:-.01em}
.card .group{display:inline-block;background:var(--yellow);color:var(--dark);font-size:.72rem;font-weight:700;padding:4px 11px;border-radius:999px;align-self:flex-start}
.card .desc{font-size:.9rem;line-height:1.45;color:#4a4f5a;white-space:pre-wrap;word-break:break-word}
.card .files{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.card .files a{display:inline-flex;align-items:center;gap:4px;background:#F2F2F2;border:1px solid #E6E6E6;color:#3a3f4a;text-decoration:none;border-radius:999px;padding:5px 12px;font-size:.75rem;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:border .15s,color .15s}
.card .files a:hover{border-color:var(--yellow);color:var(--dark)}
.card .files a::before{content:'📎'}
.files-block{margin-top:10px}
.files-label{font-size:.7rem;font-weight:800;color:var(--gray);text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px}
.card .files{display:flex;flex-direction:column;gap:6px}
.card .files a{display:flex;align-items:center;gap:8px;background:#F6F6F6;border:1px solid #EBEBEB;color:#3a3f4a;text-decoration:none;border-radius:12px;padding:6px 10px;transition:border .15s,color .15s,background .15s}
.card .files a:hover{border-color:var(--yellow);color:var(--dark);background:#fff}
.card .files .ficon{font-size:1rem;line-height:1;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:8px;flex-shrink:0}
.card .files .fname{font-size:.74rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.card .files a.ftype-image .ficon{background:#EAF4E8}
.card .files a.ftype-music .ficon{background:#EAEEF6}
.card .files a.ftype-document .ficon{background:#F6F0E0}
.card .files a.ftype-presentation .ficon{background:#F6E4E8}
.card .files a.ftype-other .ficon{background:#EFEFEF}
.card .foot{margin-top:auto;padding:8px 6px 2px;font-size:.78rem;color:var(--gray)}
.empty{grid-column:1/-1;background:#fff;border-radius:var(--radius);padding:48px 24px;text-align:center;color:var(--gray);box-shadow:0 1px 3px rgba(20,30,40,.06)}
.empty .big{font-size:2rem;margin-bottom:10px}
@@ -57,12 +65,31 @@ function esc(s){return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'
function fmt(d){return d?d.split('-').reverse().join('.'):'весь период'}
function showImg(src){document.getElementById('lightboxImg').src=src;document.getElementById('lightbox').classList.add('open')}
function isImageFile(name){return /\.(jpe?g|png|gif|webp|bmp|avif|svg|ico)$/i.test(name||'')}
function fileType(name){
if(/\.(jpe?g|png|gif|webp|bmp|avif|svg|ico)$/i.test(name||'')) return 'image';
if(/\.(mp3|wav|ogg|flac|m4a|aac|opus)$/i.test(name||'')) return 'music';
if(/\.(pptx?|odp|key)$/i.test(name||'')) return 'presentation';
if(/\.(pdf|docx?|xlsx?|txt|rtf|odt|ods|csv|md)$/i.test(name||'')) return 'document';
return 'other';
}
function fileIcon(t){
const icons = {image:'🖼️',music:'🎵',presentation:'📊',document:'📄',other:'📁'};
return icons[t]||icons.other;
}
function filesHTML(files){
if(!files||!files.length)return '';
return `<div class="files">${files.map(f=>isImageFile(f.name)
?`<a href="#" onclick="showImg('/api/files/${f.token}');return false;" title="Открыть">${esc(f.name)}</a>`
:`<a href="/api/files/${f.token}" download title="Скачать">${esc(f.name)}</a>`
).join('')}</div>`;
return `<div class="files-block">
<div class="files-label">Работы резидента</div>
<div class="files">${files.map(f=>{
const t = fileType(f.name);
return `<a class="ftype-${t}" ${isImageFile(f.name)
?`href="#" onclick="showImg('/api/files/${f.token}');return false;" title="Открыть"`
:`href="/api/files/${f.token}" download title="Скачать"`}>
<span class="ficon">${fileIcon(t)}</span>
<span class="fname">${esc(f.name)}</span>
</a>`;
}).join('')}</div>
</div>`;
}
(async()=>{