feat: 공유 링크 복사 기능 및 업로드 확인 버튼 추가
- 파일 미리보기 모달 공유 링크 복사 버튼 → 클립보드 복사 + 토스트 알림 - 업로드 완료 후 확인 버튼 표시 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+20
-2
@@ -913,13 +913,20 @@ const UploadModal = ({ onClose, onUploaded, accent, categories, users }) => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{uploads.length > 0 && uploads.every(u => u.progress === 100 || u.progress < 0) && (
|
||||||
|
<div style={{ display:'flex', justifyContent:'flex-end', marginTop:16 }}>
|
||||||
|
<button className="btn btn-accent" onClick={onClose} style={{ background:accent, borderColor:accent }}>
|
||||||
|
<Icon name="check" size={14} />확인
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const PreviewModal = ({ file, onClose, onDownload, onStar, accent, categories }) => {
|
const PreviewModal = ({ file, onClose, onDownload, onStar, onCopyLink, accent, categories }) => {
|
||||||
if (!file) return null;
|
if (!file) return null;
|
||||||
return (
|
return (
|
||||||
<div className="modal-bg" onClick={onClose}>
|
<div className="modal-bg" onClick={onClose}>
|
||||||
@@ -981,7 +988,7 @@ const PreviewModal = ({ file, onClose, onDownload, onStar, accent, categories })
|
|||||||
<Icon name="star" size={14} stroke={file.starred ? 2.5 : 1.75} style={{ color: file.starred ? "#e8a317" : "currentColor" }} />
|
<Icon name="star" size={14} stroke={file.starred ? 2.5 : 1.75} style={{ color: file.starred ? "#e8a317" : "currentColor" }} />
|
||||||
{file.starred ? "즐겨찾기 해제" : "즐겨찾기 추가"}
|
{file.starred ? "즐겨찾기 해제" : "즐겨찾기 추가"}
|
||||||
</button>
|
</button>
|
||||||
<button className="btn btn-ghost" style={{ justifyContent:"center" }}><Icon name="link" size={14} />공유 링크 복사</button>
|
<button className="btn btn-ghost" style={{ justifyContent:"center" }} onClick={() => onCopyLink(file)}><Icon name="link" size={14} />공유 링크 복사</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1133,6 +1140,16 @@ function App() {
|
|||||||
} catch { showToast("오류가 발생했습니다"); }
|
} catch { showToast("오류가 발생했습니다"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onCopyLink = async f => {
|
||||||
|
const url = `${window.location.origin}/api/files/${f.id}/download`;
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
showToast('링크가 클립보드에 복사되었습니다');
|
||||||
|
} catch {
|
||||||
|
showToast('복사에 실패했습니다');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const onBulkDownload = () => { showToast(`${selected.size}개 파일을 ZIP으로 다운로드합니다`); setSelected(new Set()); };
|
const onBulkDownload = () => { showToast(`${selected.size}개 파일을 ZIP으로 다운로드합니다`); setSelected(new Set()); };
|
||||||
|
|
||||||
const onBulkDelete = async () => {
|
const onBulkDelete = async () => {
|
||||||
@@ -1204,6 +1221,7 @@ function App() {
|
|||||||
onClose={() => setPreviewing(null)}
|
onClose={() => setPreviewing(null)}
|
||||||
onDownload={f => { onDownload(f); setPreviewing(null); }}
|
onDownload={f => { onDownload(f); setPreviewing(null); }}
|
||||||
onStar={id => toggleStar(id)}
|
onStar={id => toggleStar(id)}
|
||||||
|
onCopyLink={onCopyLink}
|
||||||
accent={t.accent}
|
accent={t.accent}
|
||||||
categories={categories}
|
categories={categories}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user