feat(recipe-form): reject files > 5 MB and show Max. 5 MB hint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,10 +61,19 @@
|
||||
);
|
||||
let steps = $state(initial?.steps.map((s) => s.instruction) ?? ['']);
|
||||
let heroImageUrl = $state<string | null>(initial?.heroImageUrl ?? null);
|
||||
let imageError = $state<string | null>(null);
|
||||
|
||||
const MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
||||
|
||||
function handleImageChange(e: Event) {
|
||||
const file = (e.currentTarget as HTMLInputElement).files?.[0];
|
||||
if (!file) return;
|
||||
if (file.size > MAX_IMAGE_BYTES) {
|
||||
imageError = 'Datei zu groß. Maximal 5 MB erlaubt.';
|
||||
(e.currentTarget as HTMLInputElement).value = '';
|
||||
return;
|
||||
}
|
||||
imageError = null;
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
heroImageUrl = reader.result as string;
|
||||
@@ -196,6 +205,11 @@
|
||||
/>
|
||||
{heroImageUrl ? 'Bild ändern' : 'Bild hochladen'}
|
||||
</label>
|
||||
{#if imageError}
|
||||
<p class="mt-[6px] text-[12px] text-[var(--color-error)]">{imageError}</p>
|
||||
{:else}
|
||||
<p class="mt-[6px] text-[11px] text-[var(--color-text-muted)]">Max. 5 MB</p>
|
||||
{/if}
|
||||
<input type="hidden" name="heroImageUrl" value={heroImageUrl ?? ''} />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -162,4 +162,31 @@ describe('RecipeForm', () => {
|
||||
render(RecipeForm, { props: emptyProps });
|
||||
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows Max. 5 MB hint below upload button', () => {
|
||||
render(RecipeForm, { props: emptyProps });
|
||||
expect(screen.getByText('Max. 5 MB')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows error when selected file exceeds 5 MB', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(RecipeForm, { props: emptyProps });
|
||||
|
||||
const oversizedFile = new File(['x'.repeat(6 * 1024 * 1024)], 'big.jpg', { type: 'image/jpeg' });
|
||||
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
|
||||
await user.upload(fileInput, oversizedFile);
|
||||
|
||||
expect(screen.getByText(/datei zu groß/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not show file size error for file within 5 MB', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(RecipeForm, { props: emptyProps });
|
||||
|
||||
const okFile = new File(['x'.repeat(1 * 1024 * 1024)], 'small.jpg', { type: 'image/jpeg' });
|
||||
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
|
||||
await user.upload(fileInput, okFile);
|
||||
|
||||
expect(screen.queryByText(/datei zu groß/i)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user