fix: move upload endpoint to root /upload route (works from both app and atelier)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,117 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
let uploading = $state(false);
|
|
||||||
let lastFile = $state('');
|
|
||||||
let dragOver = $state(false);
|
|
||||||
|
|
||||||
async function upload(file: File) {
|
|
||||||
uploading = true;
|
|
||||||
const fd = new FormData();
|
|
||||||
fd.append('file', file);
|
|
||||||
try {
|
|
||||||
const res = await fetch('/upload', { method: 'POST', body: fd, credentials: 'include' });
|
|
||||||
const data = await res.json();
|
|
||||||
lastFile = data.filename || '';
|
|
||||||
} catch { lastFile = 'Error'; }
|
|
||||||
uploading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDrop(e: DragEvent) {
|
|
||||||
e.preventDefault();
|
|
||||||
dragOver = false;
|
|
||||||
const file = e.dataTransfer?.files[0];
|
|
||||||
if (file) upload(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlePaste(e: ClipboardEvent) {
|
|
||||||
const items = e.clipboardData?.items;
|
|
||||||
if (!items) return;
|
|
||||||
for (const item of items) {
|
|
||||||
if (item.type.startsWith('image/')) {
|
|
||||||
const file = item.getAsFile();
|
|
||||||
if (file) upload(file);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleFileInput(e: Event) {
|
|
||||||
const input = e.target as HTMLInputElement;
|
|
||||||
if (input.files?.[0]) upload(input.files[0]);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:window onpaste={handlePaste} />
|
|
||||||
|
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
||||||
<div class="upload-page"
|
|
||||||
ondragover={(e) => { e.preventDefault(); dragOver = true; }}
|
|
||||||
ondragleave={() => dragOver = false}
|
|
||||||
ondrop={handleDrop}
|
|
||||||
>
|
|
||||||
<div class="upload-zone" class:dragover={dragOver}>
|
|
||||||
{#if uploading}
|
|
||||||
<div class="upload-status">Uploading...</div>
|
|
||||||
{:else if lastFile}
|
|
||||||
<div class="upload-done">
|
|
||||||
<div class="upload-check">Saved</div>
|
|
||||||
<div class="upload-filename">{lastFile}</div>
|
|
||||||
<button class="upload-another" onclick={() => lastFile = ''}>Upload another</button>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div class="upload-prompt">
|
|
||||||
<div class="upload-icon">
|
|
||||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
|
||||||
</div>
|
|
||||||
<div class="upload-text">Drop a file, paste a screenshot, or click to upload</div>
|
|
||||||
<label class="upload-btn">
|
|
||||||
Browse files
|
|
||||||
<input type="file" accept="image/*,.pdf,.txt,.md" onchange={handleFileInput} hidden />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.upload-page {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-height: 80vh;
|
|
||||||
padding: 24px;
|
|
||||||
}
|
|
||||||
.upload-zone {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 480px;
|
|
||||||
min-height: 280px;
|
|
||||||
border: 2px dashed rgba(35,26,17,0.15);
|
|
||||||
border-radius: 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 40px;
|
|
||||||
transition: all 200ms;
|
|
||||||
background: rgba(255,252,248,0.5);
|
|
||||||
}
|
|
||||||
.upload-zone.dragover {
|
|
||||||
border-color: rgba(179,92,50,0.4);
|
|
||||||
background: rgba(255,248,242,0.8);
|
|
||||||
}
|
|
||||||
.upload-prompt { text-align: center; }
|
|
||||||
.upload-icon { color: #8c7b69; margin-bottom: 16px; }
|
|
||||||
.upload-text { color: #5c5046; font-size: 1rem; margin-bottom: 16px; line-height: 1.5; }
|
|
||||||
.upload-btn {
|
|
||||||
display: inline-block; padding: 10px 24px; border-radius: 999px;
|
|
||||||
background: #1e1812; color: white; font-size: 0.88rem; font-weight: 600;
|
|
||||||
cursor: pointer; transition: opacity 160ms;
|
|
||||||
}
|
|
||||||
.upload-btn:hover { opacity: 0.9; }
|
|
||||||
.upload-status { font-size: 1.1rem; color: #5c5046; }
|
|
||||||
.upload-done { text-align: center; }
|
|
||||||
.upload-check { font-size: 1.2rem; font-weight: 700; color: #059669; margin-bottom: 8px; }
|
|
||||||
.upload-filename { font-size: 0.88rem; color: #5c5046; font-family: var(--mono); margin-bottom: 16px; }
|
|
||||||
.upload-another {
|
|
||||||
padding: 8px 18px; border-radius: 999px; border: 1px solid rgba(35,26,17,0.12);
|
|
||||||
background: none; color: #5c5046; font-size: 0.85rem; cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Reference in New Issue
Block a user