feat(ui): refonte de l'interface
This commit is contained in:
1 parent
3ede3e808c
commit
09eb1fa3aa
79 files changed
+5323
-3514
No files matched your search
@@ -1,16 +1,18 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-3">
|
||||
<div>
|
||||
<label class="settings-label">Nom</label>
|
||||
<input v-model="name" placeholder="Mon client torrent" class="settings-input" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="settings-label">Type</label>
|
||||
<select v-model="type" @change="onTypeChange" class="settings-input">
|
||||
<option value="">Choisir un type...</option>
|
||||
<option v-for="def in definitions" :key="def.id" :value="def.id">{{ def.label }}</option>
|
||||
</select>
|
||||
<div class="flex flex-col gap-3.5">
|
||||
<div class="grid sm:grid-cols-2 gap-3.5">
|
||||
<div class="flex flex-col gap-[7px]">
|
||||
<label for="client-name" class="field-label">Nom</label>
|
||||
<input id="client-name" v-model="name" placeholder="Mon client torrent" class="field" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-[7px]">
|
||||
<label for="client-type" class="field-label">Type</label>
|
||||
<select id="client-type" v-model="type" @change="onTypeChange" class="field">
|
||||
<option value="">Choisir un type…</option>
|
||||
<option v-for="def in definitions" :key="def.id" :value="def.id">{{ def.label }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Champs principaux -->
|
||||
@@ -23,18 +25,18 @@
|
||||
:description="fieldTooltip(field.key)"
|
||||
@update:model-value="config[field.key] = $event"
|
||||
/>
|
||||
<template v-else>
|
||||
<label class="settings-label">
|
||||
{{ field.label }}
|
||||
<span v-if="field.required" class="text-red-400 ml-0.5">*</span>
|
||||
<div v-else class="flex flex-col gap-[7px]">
|
||||
<label :for="`client-${field.key}`" class="field-label">
|
||||
{{ field.label }}<span v-if="field.required" class="text-err ml-0.5">*</span>
|
||||
</label>
|
||||
<input
|
||||
:id="`client-${field.key}`"
|
||||
v-model="config[field.key]"
|
||||
:type="field.type === 'password' ? 'password' : 'text'"
|
||||
:placeholder="field.placeholder ?? ''"
|
||||
class="settings-input"
|
||||
class="field"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Paramètres avancés -->
|
||||
@@ -42,17 +44,18 @@
|
||||
<button
|
||||
type="button"
|
||||
@click="advancedOpen = !advancedOpen"
|
||||
class="flex items-center gap-1.5 text-xs text-muted hover:text-primary transition-colors w-full py-1"
|
||||
class="flex items-center gap-1.5 text-meta text-secondary hover:text-primary transition-colors w-full py-1"
|
||||
:aria-expanded="advancedOpen"
|
||||
>
|
||||
<ChevronDown
|
||||
:size="13"
|
||||
:size="14"
|
||||
class="transition-transform duration-200 shrink-0"
|
||||
:class="advancedOpen ? 'rotate-180' : ''"
|
||||
/>
|
||||
Paramètres avancés
|
||||
</button>
|
||||
|
||||
<div v-if="advancedOpen" class="flex flex-col gap-3 mt-2 pl-3 border-l border-border">
|
||||
<div v-if="advancedOpen" class="flex flex-col gap-3.5 mt-2.5 pl-3.5 border-l border-hover">
|
||||
<div v-for="field in advancedFields" :key="field.key">
|
||||
<SettingsToggle
|
||||
v-if="field.type === 'boolean'"
|
||||
@@ -61,42 +64,35 @@
|
||||
:description="fieldTooltip(field.key)"
|
||||
@update:model-value="config[field.key] = $event"
|
||||
/>
|
||||
<template v-else>
|
||||
<label class="settings-label flex items-center gap-1.5">
|
||||
{{ field.label }}
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-4 h-4 rounded-full border border-border text-[10px] text-muted cursor-default leading-none shrink-0 relative group"
|
||||
tabindex="-1"
|
||||
>
|
||||
i
|
||||
<span class="absolute bottom-full left-1/2 -translate-x-1/2 mb-1.5 w-56 text-[11px] text-secondary bg-card border border-border rounded-lg px-2.5 py-1.5 shadow-lg pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity z-10 leading-relaxed">
|
||||
{{ fieldTooltip(field.key) }}
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div v-else class="flex flex-col gap-[7px]">
|
||||
<label :for="`client-${field.key}`" class="field-label">{{ field.label }}</label>
|
||||
<input
|
||||
:id="`client-${field.key}`"
|
||||
v-model="config[field.key]"
|
||||
:type="field.type === 'password' ? 'password' : 'text'"
|
||||
:placeholder="field.placeholder ?? ''"
|
||||
class="settings-input"
|
||||
class="field"
|
||||
/>
|
||||
</template>
|
||||
<p v-if="fieldTooltip(field.key)" class="text-xs text-muted">{{ fieldTooltip(field.key) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<p v-if="!tested && type" class="text-xs text-muted">
|
||||
<p v-if="!tested && type" class="text-meta text-muted">
|
||||
Testez la connexion avant d'enregistrer.
|
||||
</p>
|
||||
|
||||
<div class="flex gap-2 pt-1">
|
||||
<div class="flex items-center gap-2.5 pt-1 flex-wrap">
|
||||
<button @click="save" :disabled="saving || !tested" class="btn-primary">
|
||||
{{ saving ? '...' : 'Enregistrer' }}
|
||||
{{ saving ? 'Enregistrement…' : 'Enregistrer' }}
|
||||
</button>
|
||||
<button @click="test" :disabled="testing || !type" class="btn-secondary">
|
||||
{{ testing ? '...' : tested ? 'Testé ✓' : 'Tester' }}
|
||||
<Loader v-if="testing" :size="14" class="animate-spin" />
|
||||
<Check v-else-if="tested" :size="14" class="text-ok" />
|
||||
{{ testing ? 'Test…' : tested ? 'Connexion testée' : 'Tester' }}
|
||||
</button>
|
||||
<button v-if="showCancel" @click="emit('cancel')" class="btn-ghost ml-auto">Annuler</button>
|
||||
</div>
|
||||
@@ -105,7 +101,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { ChevronDown } from 'lucide-vue-next'
|
||||
import { Check, ChevronDown, Loader } from 'lucide-vue-next'
|
||||
import SettingsToggle from '@/components/settings/SettingsToggle.vue'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
import type { TorrentClientConfig, TorrentClientDefinition, SavedTorrentClient } from '@/types/torrent-client'
|
||||
|
||||
Reference in new issue
Block a user