mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-21 21:06:42 +02:00
feat(chat): add auto title generation, inline renaming, and styled delete modal
- Fix missing conversationsStore import for auto title generation - Make model ID dynamic in generateTitle() with error handling and fallback - Add inline editing for manual conversation renaming in sidebar - Add updateConversationTitle API endpoint and store method - Replace browser confirm() with styled ConfirmationModal for delete - Update Modal and ConfirmationModal with glassmorphism styling - Add DEV_BYPASS_AUTH and GOOGLE_GENAI_API_KEY to env generation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a32c4f0a16
commit
05fe8ca5b6
14 changed files with 447 additions and 71 deletions
|
|
@ -31,9 +31,9 @@
|
|||
* ```
|
||||
*/
|
||||
|
||||
import { Warning, WarningCircle, Info } from '@manacore/shared-icons';
|
||||
import { Warning, WarningCircle, Info, X, Trash, Check } from '@manacore/shared-icons';
|
||||
import Modal from './Modal.svelte';
|
||||
import { Text, Button } from '../atoms';
|
||||
import { Text } from '../atoms';
|
||||
|
||||
type ConfirmationVariant = 'danger' | 'warning' | 'info';
|
||||
|
||||
|
|
@ -72,19 +72,25 @@
|
|||
|
||||
const variantConfig: Record<
|
||||
ConfirmationVariant,
|
||||
{ iconColor: string; buttonVariant: 'danger' | 'primary' }
|
||||
{ iconColor: string; iconBg: string; buttonColor: string; buttonHover: string }
|
||||
> = {
|
||||
danger: {
|
||||
iconColor: 'text-red-500',
|
||||
buttonVariant: 'danger',
|
||||
iconBg: 'bg-red-500/10',
|
||||
buttonColor: 'bg-red-500 text-white',
|
||||
buttonHover: 'hover:bg-red-600 hover:shadow-lg hover:shadow-red-500/25',
|
||||
},
|
||||
warning: {
|
||||
iconColor: 'text-yellow-500',
|
||||
buttonVariant: 'primary',
|
||||
iconBg: 'bg-yellow-500/10',
|
||||
buttonColor: 'bg-yellow-500 text-white',
|
||||
buttonHover: 'hover:bg-yellow-600 hover:shadow-lg hover:shadow-yellow-500/25',
|
||||
},
|
||||
info: {
|
||||
iconColor: 'text-blue-500',
|
||||
buttonVariant: 'primary',
|
||||
iconBg: 'bg-blue-500/10',
|
||||
buttonColor: 'bg-blue-500 text-white',
|
||||
buttonHover: 'hover:bg-blue-600 hover:shadow-lg hover:shadow-blue-500/25',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -97,7 +103,7 @@
|
|||
|
||||
<Modal {visible} {onClose} {title} maxWidth="sm">
|
||||
{#snippet icon()}
|
||||
<div class="p-2 rounded-full bg-menu-hover {config.iconColor}">
|
||||
<div class="p-2.5 rounded-xl {config.iconBg} {config.iconColor}">
|
||||
{#if variant === 'danger'}
|
||||
<Warning size={20} weight="bold" />
|
||||
{:else if variant === 'warning'}
|
||||
|
|
@ -117,13 +123,46 @@
|
|||
</div>
|
||||
|
||||
{#snippet footer()}
|
||||
<div class="flex gap-3 justify-end">
|
||||
<Button variant="ghost" onclick={onClose} disabled={loading}>
|
||||
{cancelLabel}
|
||||
</Button>
|
||||
<Button variant={config.buttonVariant} onclick={handleConfirm} {loading}>
|
||||
<div class="flex flex-col gap-3">
|
||||
<!-- Confirm Button -->
|
||||
<button
|
||||
onclick={handleConfirm}
|
||||
disabled={loading}
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-xl font-semibold text-sm
|
||||
{config.buttonColor} {config.buttonHover}
|
||||
transition-all duration-200 hover:-translate-y-0.5 active:translate-y-0
|
||||
disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:translate-y-0 disabled:hover:shadow-none"
|
||||
>
|
||||
{#if loading}
|
||||
<svg class="h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
|
||||
<path
|
||||
class="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
/>
|
||||
</svg>
|
||||
{:else if variant === 'danger'}
|
||||
<Trash size={18} weight="bold" />
|
||||
{:else}
|
||||
<Check size={18} weight="bold" />
|
||||
{/if}
|
||||
{confirmLabel}
|
||||
</Button>
|
||||
</button>
|
||||
|
||||
<!-- Cancel Button -->
|
||||
<button
|
||||
onclick={onClose}
|
||||
disabled={loading}
|
||||
class="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-xl font-semibold text-sm
|
||||
bg-black/5 dark:bg-white/10 text-foreground
|
||||
hover:bg-black/10 dark:hover:bg-white/20 hover:shadow-md
|
||||
transition-all duration-200 hover:-translate-y-0.5 active:translate-y-0
|
||||
disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:translate-y-0"
|
||||
>
|
||||
<X size={18} weight="bold" />
|
||||
{cancelLabel}
|
||||
</button>
|
||||
</div>
|
||||
{/snippet}
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -65,14 +65,14 @@
|
|||
<div
|
||||
class="relative flex max-h-[90vh] w-full {maxWidthClasses[
|
||||
maxWidth
|
||||
]} flex-col rounded-xl border border-theme bg-menu shadow-xl"
|
||||
]} flex-col rounded-2xl border border-black/10 dark:border-white/20 bg-white/80 dark:bg-white/10 backdrop-blur-xl shadow-2xl"
|
||||
onclick={(e) => e.stopPropagation()}
|
||||
onkeydown={(e) => e.stopPropagation()}
|
||||
>
|
||||
{#if showHeader}
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between p-6 border-b border-theme">
|
||||
<div class="flex items-center gap-2 flex-1">
|
||||
<div class="flex items-center justify-between p-6 border-b border-black/10 dark:border-white/10">
|
||||
<div class="flex items-center gap-3 flex-1">
|
||||
{#if icon}
|
||||
{@render icon()}
|
||||
{/if}
|
||||
|
|
@ -84,10 +84,10 @@
|
|||
</div>
|
||||
<button
|
||||
onclick={onClose}
|
||||
class="p-2 rounded-full hover:bg-menu-hover transition-colors"
|
||||
class="p-2 rounded-xl bg-black/5 dark:bg-white/10 hover:bg-black/10 dark:hover:bg-white/20 transition-all duration-200 hover:scale-105"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X size={20} weight="bold" class="text-theme-muted" />
|
||||
<X size={18} weight="bold" class="text-muted-foreground" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
|
||||
<!-- Footer (optional) -->
|
||||
{#if footer}
|
||||
<div class="border-t border-theme p-6">
|
||||
<div class="border-t border-black/10 dark:border-white/10 p-6">
|
||||
{@render footer()}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue