mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 01:01:09 +02:00
feat(shared-uload): add password protection and expiration to ShareModal
Adds collapsible "Erweiterte Optionen" section with: - Password protection toggle with text input - Expiration date toggle with datetime-local picker - Footer badges showing active protection/expiry on created links Both fields are passed through to createShortLink and stored in IndexedDB. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ae73f70ad0
commit
14701a973d
3 changed files with 85 additions and 5 deletions
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { X, Copy, QrCode, Link, ArrowSquareOut } from '@manacore/shared-icons';
|
||||
import { X, Copy, QrCode, Link, ArrowSquareOut, Lock, Clock } from '@manacore/shared-icons';
|
||||
import type { CreatedLink, CreateShortLinkOptions } from './types';
|
||||
import { createShortLink, isSharedUloadReady, getBaseUrl } from './create-link';
|
||||
import { getQrCodeUrl, getShortUrl, downloadQrCode } from './utils';
|
||||
|
|
@ -18,20 +18,30 @@
|
|||
|
||||
let customCode = $state('');
|
||||
let useCustomCode = $state(false);
|
||||
let password = $state('');
|
||||
let usePassword = $state(false);
|
||||
let expiresAt = $state('');
|
||||
let useExpiry = $state(false);
|
||||
let createdLink = $state<CreatedLink | null>(null);
|
||||
let creating = $state(false);
|
||||
let error = $state('');
|
||||
let copied = $state(false);
|
||||
let showQr = $state(false);
|
||||
let showAdvanced = $state(false);
|
||||
|
||||
function reset() {
|
||||
customCode = '';
|
||||
useCustomCode = false;
|
||||
password = '';
|
||||
usePassword = false;
|
||||
expiresAt = '';
|
||||
useExpiry = false;
|
||||
createdLink = null;
|
||||
creating = false;
|
||||
error = '';
|
||||
copied = false;
|
||||
showQr = false;
|
||||
showAdvanced = false;
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
|
|
@ -55,6 +65,8 @@
|
|||
source,
|
||||
description: description || undefined,
|
||||
customCode: useCustomCode && customCode ? customCode : undefined,
|
||||
password: usePassword && password ? password : undefined,
|
||||
expiresAt: useExpiry && expiresAt ? new Date(expiresAt).toISOString() : undefined,
|
||||
};
|
||||
|
||||
const link = await createShortLink(options);
|
||||
|
|
@ -160,6 +172,61 @@
|
|||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Advanced Options Toggle -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (showAdvanced = !showAdvanced)}
|
||||
class="flex items-center gap-1.5 text-xs text-gray-400 hover:text-gray-300 transition-colors"
|
||||
>
|
||||
<span class="transition-transform {showAdvanced ? 'rotate-90' : ''}">▶</span>
|
||||
Erweiterte Optionen
|
||||
</button>
|
||||
|
||||
{#if showAdvanced}
|
||||
<div class="space-y-3 rounded-lg bg-white/5 p-3">
|
||||
<!-- Password Protection -->
|
||||
<div>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={usePassword}
|
||||
class="rounded border-gray-600 bg-gray-800 text-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
<Lock size={14} class="text-gray-400" />
|
||||
<span class="text-sm text-gray-300">Passwortschutz</span>
|
||||
</label>
|
||||
{#if usePassword}
|
||||
<input
|
||||
type="text"
|
||||
bind:value={password}
|
||||
placeholder="Passwort eingeben"
|
||||
class="mt-2 w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm text-white placeholder-gray-500 focus:border-indigo-500 focus:outline-none"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Expiration -->
|
||||
<div>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={useExpiry}
|
||||
class="rounded border-gray-600 bg-gray-800 text-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
<Clock size={14} class="text-gray-400" />
|
||||
<span class="text-sm text-gray-300">Ablaufdatum</span>
|
||||
</label>
|
||||
{#if useExpiry}
|
||||
<input
|
||||
type="datetime-local"
|
||||
bind:value={expiresAt}
|
||||
class="mt-2 w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm text-white focus:border-indigo-500 focus:outline-none"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if error}
|
||||
<p class="text-sm text-red-400">{error}</p>
|
||||
{/if}
|
||||
|
|
@ -233,11 +300,22 @@
|
|||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Footer: Source badge -->
|
||||
<!-- Footer: Source badge + protection info -->
|
||||
<div class="border-t border-white/10 px-5 py-3">
|
||||
<p class="text-xs text-gray-500">
|
||||
Erstellt via <span class="text-gray-400">{source}</span> · Sichtbar in uLoad
|
||||
</p>
|
||||
<div class="flex items-center gap-3 text-xs text-gray-500">
|
||||
<span>via <span class="text-gray-400">{source}</span></span>
|
||||
{#if createdLink && usePassword && password}
|
||||
<span class="flex items-center gap-1 text-amber-500">
|
||||
<Lock size={10} /> Passwortgeschützt
|
||||
</span>
|
||||
{/if}
|
||||
{#if createdLink && useExpiry && expiresAt}
|
||||
<span class="flex items-center gap-1 text-blue-400">
|
||||
<Clock size={10} /> Läuft ab
|
||||
</span>
|
||||
{/if}
|
||||
<span class="ml-auto">Sichtbar in uLoad</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ export async function createShortLink(options: CreateShortLinkOptions): Promise<
|
|||
order: 0,
|
||||
source: options.source,
|
||||
expiresAt: options.expiresAt || null,
|
||||
password: options.password || null,
|
||||
qrCodeUrl,
|
||||
} as UloadLink);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export interface CreateShortLinkOptions {
|
|||
source: string;
|
||||
tags?: string[];
|
||||
expiresAt?: string;
|
||||
password?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue