refactor: tüm bileşenler leptos-shadcn-ui'ye dönüştürüldü
All checks were successful
Build MIPS Binary / build (push) Successful in 5m16s
All checks were successful
Build MIPS Binary / build (push) Successful in 5m16s
- login.rs: Card, Input, Button, Label, Alert - setup.rs: Card, Input, Button, Label, Alert - add_torrent.rs: Dialog, Input, Button, Alert - toast.rs: Alert bileşeni ile - Cargo.toml: dialog, label, alert, toast, dropdown-menu, tooltip eklendi
This commit is contained in:
98
Cargo.lock
generated
98
Cargo.lock
generated
@@ -1260,17 +1260,23 @@ dependencies = [
|
|||||||
"gloo-timers",
|
"gloo-timers",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"leptos",
|
"leptos",
|
||||||
|
"leptos-shadcn-alert",
|
||||||
"leptos-shadcn-avatar",
|
"leptos-shadcn-avatar",
|
||||||
"leptos-shadcn-badge",
|
"leptos-shadcn-badge",
|
||||||
"leptos-shadcn-button",
|
"leptos-shadcn-button",
|
||||||
"leptos-shadcn-card",
|
"leptos-shadcn-card",
|
||||||
"leptos-shadcn-context-menu",
|
"leptos-shadcn-context-menu",
|
||||||
|
"leptos-shadcn-dialog",
|
||||||
|
"leptos-shadcn-dropdown-menu",
|
||||||
"leptos-shadcn-input",
|
"leptos-shadcn-input",
|
||||||
|
"leptos-shadcn-label",
|
||||||
"leptos-shadcn-progress",
|
"leptos-shadcn-progress",
|
||||||
"leptos-shadcn-scroll-area",
|
"leptos-shadcn-scroll-area",
|
||||||
"leptos-shadcn-separator",
|
"leptos-shadcn-separator",
|
||||||
"leptos-shadcn-sheet",
|
"leptos-shadcn-sheet",
|
||||||
"leptos-shadcn-tabs",
|
"leptos-shadcn-tabs",
|
||||||
|
"leptos-shadcn-toast",
|
||||||
|
"leptos-shadcn-tooltip",
|
||||||
"leptos-use",
|
"leptos-use",
|
||||||
"leptos_router",
|
"leptos_router",
|
||||||
"log",
|
"log",
|
||||||
@@ -2159,6 +2165,21 @@ dependencies = [
|
|||||||
"send_wrapper",
|
"send_wrapper",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos-shadcn-alert"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "884551df61ade405bdb61b0d5a92a3a88b3a7af7a2d283b8d3e942ae0d71309c"
|
||||||
|
dependencies = [
|
||||||
|
"leptos",
|
||||||
|
"leptos-node-ref",
|
||||||
|
"leptos-shadcn-signal-management",
|
||||||
|
"leptos-struct-component",
|
||||||
|
"leptos-style",
|
||||||
|
"tailwind_fuse",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos-shadcn-avatar"
|
name = "leptos-shadcn-avatar"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -2234,6 +2255,36 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos-shadcn-dialog"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3fdbb636393b150c2db1e37d44a6832e9dde177ce2e81281932fefad8bde98e"
|
||||||
|
dependencies = [
|
||||||
|
"leptos",
|
||||||
|
"leptos-node-ref",
|
||||||
|
"leptos-shadcn-signal-management",
|
||||||
|
"leptos-struct-component",
|
||||||
|
"leptos-style",
|
||||||
|
"tailwind_fuse",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos-shadcn-dropdown-menu"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f50189623a176386a30443d281483c5aa6cc34dc45fa11c3e53bd187ffccde21"
|
||||||
|
dependencies = [
|
||||||
|
"leptos",
|
||||||
|
"leptos-node-ref",
|
||||||
|
"leptos-shadcn-signal-management",
|
||||||
|
"leptos-struct-component",
|
||||||
|
"leptos-style",
|
||||||
|
"tailwind_fuse",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos-shadcn-input"
|
name = "leptos-shadcn-input"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -2250,6 +2301,21 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos-shadcn-label"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e7cad4b5fae11df9bf3b1d4265a56509a9bb7d3a8580e7487f398b733eadf0c"
|
||||||
|
dependencies = [
|
||||||
|
"leptos",
|
||||||
|
"leptos-node-ref",
|
||||||
|
"leptos-shadcn-signal-management",
|
||||||
|
"leptos-struct-component",
|
||||||
|
"leptos-style",
|
||||||
|
"tailwind_fuse",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos-shadcn-progress"
|
name = "leptos-shadcn-progress"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -2339,6 +2405,38 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos-shadcn-toast"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3315f7ed844e3286704cc7b57db7209cad592c11eee770f5dc48ebdc92d66cfb"
|
||||||
|
dependencies = [
|
||||||
|
"gloo-timers",
|
||||||
|
"leptos",
|
||||||
|
"leptos-node-ref",
|
||||||
|
"leptos-shadcn-signal-management",
|
||||||
|
"leptos-struct-component",
|
||||||
|
"leptos-style",
|
||||||
|
"tailwind_fuse",
|
||||||
|
"uuid",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos-shadcn-tooltip"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e41d37932d700444e1d3a21f10f198c3c9e76dde3fd78d58da4b5a099939fd7"
|
||||||
|
dependencies = [
|
||||||
|
"leptos",
|
||||||
|
"leptos-node-ref",
|
||||||
|
"leptos-shadcn-signal-management",
|
||||||
|
"leptos-struct-component",
|
||||||
|
"leptos-style",
|
||||||
|
"tailwind_fuse",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos-struct-component"
|
name = "leptos-struct-component"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|||||||
@@ -46,3 +46,9 @@ leptos-shadcn-avatar = "0.8"
|
|||||||
leptos-shadcn-sheet = "0.8"
|
leptos-shadcn-sheet = "0.8"
|
||||||
leptos-shadcn-tabs = "0.8"
|
leptos-shadcn-tabs = "0.8"
|
||||||
leptos-shadcn-scroll-area = "0.8"
|
leptos-shadcn-scroll-area = "0.8"
|
||||||
|
leptos-shadcn-dialog = "0.8"
|
||||||
|
leptos-shadcn-label = "0.8"
|
||||||
|
leptos-shadcn-alert = "0.8"
|
||||||
|
leptos-shadcn-toast = "0.8"
|
||||||
|
leptos-shadcn-dropdown-menu = "0.8"
|
||||||
|
leptos-shadcn-tooltip = "0.8"
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos::task::spawn_local;
|
use leptos::task::spawn_local;
|
||||||
|
use leptos_shadcn_card::{Card, CardHeader, CardContent};
|
||||||
|
use leptos_shadcn_input::Input;
|
||||||
|
use leptos_shadcn_button::Button;
|
||||||
|
use leptos_shadcn_label::Label;
|
||||||
|
use leptos_shadcn_alert::{Alert, AlertDescription, AlertVariant};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Login() -> impl IntoView {
|
pub fn Login() -> impl IntoView {
|
||||||
@@ -32,8 +37,8 @@ pub fn Login() -> impl IntoView {
|
|||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class="flex items-center justify-center min-h-screen bg-muted/40 px-4">
|
<div class="flex items-center justify-center min-h-screen bg-muted/40 px-4">
|
||||||
<div class="w-full max-w-sm rounded-xl border border-border bg-card text-card-foreground shadow-lg">
|
<Card class="w-full max-w-sm shadow-lg">
|
||||||
<div class="flex flex-col space-y-1.5 p-6 pb-2 items-center">
|
<CardHeader class="pb-2 items-center">
|
||||||
<div class="w-12 h-12 bg-primary rounded-xl flex items-center justify-center text-primary-foreground shadow-sm mb-4">
|
<div class="w-12 h-12 bg-primary rounded-xl flex items-center justify-center text-primary-foreground shadow-sm mb-4">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0112 21 8.25 8.25 0 016.038 7.048 8.287 8.287 0 009 9.6a8.983 8.983 0 013.361-6.867 8.21 8.25 0 003 2.48z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0112 21 8.25 8.25 0 016.038 7.048 8.287 8.287 0 009 9.6a8.983 8.983 0 013.361-6.867 8.21 8.25 0 003 2.48z" />
|
||||||
@@ -42,56 +47,53 @@ pub fn Login() -> impl IntoView {
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="font-semibold tracking-tight text-2xl">"VibeTorrent"</h3>
|
<h3 class="font-semibold tracking-tight text-2xl">"VibeTorrent"</h3>
|
||||||
<p class="text-sm text-muted-foreground">"Hesabınıza giriş yapın"</p>
|
<p class="text-sm text-muted-foreground">"Hesabınıza giriş yapın"</p>
|
||||||
</div>
|
</CardHeader>
|
||||||
|
|
||||||
<div class="p-6 pt-4">
|
<CardContent class="pt-4">
|
||||||
<form on:submit=handle_login class="space-y-4">
|
<form on:submit=handle_login class="space-y-4">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium leading-none">"Kullanıcı Adı"</label>
|
<Label>"Kullanıcı Adı"</Label>
|
||||||
<input
|
<Input
|
||||||
type="text"
|
input_type="text"
|
||||||
placeholder="Kullanıcı adınız"
|
placeholder="Kullanıcı adınız"
|
||||||
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
value=MaybeProp::derive(move || Some(username.0.get()))
|
||||||
prop:value=move || username.0.get()
|
on_change=Callback::new(move |val: String| username.1.set(val))
|
||||||
on:input=move |ev| username.1.set(event_target_value(&ev))
|
disabled=Signal::derive(move || loading.0.get())
|
||||||
disabled=move || loading.0.get()
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium leading-none">"Şifre"</label>
|
<Label>"Şifre"</Label>
|
||||||
<input
|
<Input
|
||||||
type="password"
|
input_type="password"
|
||||||
placeholder="******"
|
placeholder="******"
|
||||||
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
value=MaybeProp::derive(move || Some(password.0.get()))
|
||||||
prop:value=move || password.0.get()
|
on_change=Callback::new(move |val: String| password.1.set(val))
|
||||||
on:input=move |ev| password.1.set(event_target_value(&ev))
|
disabled=Signal::derive(move || loading.0.get())
|
||||||
disabled=move || loading.0.get()
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when=move || error.0.get().is_some()>
|
<Show when=move || error.0.get().is_some()>
|
||||||
<div class="rounded-md border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive">
|
<Alert variant=AlertVariant::Destructive>
|
||||||
{move || error.0.get().unwrap_or_default()}
|
<AlertDescription>
|
||||||
</div>
|
{move || error.0.get().unwrap_or_default()}
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<div class="pt-2">
|
<div class="pt-2">
|
||||||
<button
|
<Button
|
||||||
class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2 w-full"
|
class="w-full"
|
||||||
type="submit"
|
disabled=Signal::derive(move || loading.0.get())
|
||||||
disabled=move || loading.0.get()
|
|
||||||
>
|
>
|
||||||
<Show when=move || loading.0.get() fallback=|| "Giriş Yap">
|
<Show when=move || loading.0.get() fallback=|| "Giriş Yap">
|
||||||
<span class="animate-spin mr-2 h-4 w-4 border-2 border-current border-t-transparent rounded-full"></span>
|
<span class="animate-spin mr-2 h-4 w-4 border-2 border-current border-t-transparent rounded-full"></span>
|
||||||
"Giriş Yapılıyor..."
|
"Giriş Yapılıyor..."
|
||||||
</Show>
|
</Show>
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</CardContent>
|
||||||
</div>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos::task::spawn_local;
|
use leptos::task::spawn_local;
|
||||||
|
use leptos_shadcn_card::{Card, CardHeader, CardContent};
|
||||||
|
use leptos_shadcn_input::Input;
|
||||||
|
use leptos_shadcn_button::Button;
|
||||||
|
use leptos_shadcn_label::Label;
|
||||||
|
use leptos_shadcn_alert::{Alert, AlertDescription, AlertVariant};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Setup() -> impl IntoView {
|
pub fn Setup() -> impl IntoView {
|
||||||
@@ -48,8 +53,8 @@ pub fn Setup() -> impl IntoView {
|
|||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class="flex items-center justify-center min-h-screen bg-muted/40 px-4">
|
<div class="flex items-center justify-center min-h-screen bg-muted/40 px-4">
|
||||||
<div class="w-full max-w-md rounded-xl border border-border bg-card text-card-foreground shadow-lg overflow-hidden">
|
<Card class="w-full max-w-md shadow-lg overflow-hidden">
|
||||||
<div class="flex flex-col space-y-1.5 p-6 pb-2 items-center text-center">
|
<CardHeader class="pb-2 items-center text-center">
|
||||||
<div class="w-12 h-12 bg-primary rounded-xl flex items-center justify-center text-primary-foreground shadow-sm mb-4">
|
<div class="w-12 h-12 bg-primary rounded-xl flex items-center justify-center text-primary-foreground shadow-sm mb-4">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M11.42 15.17L17.25 21A2.652 2.652 0 0021 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 11-3.586-3.586l6.837-5.63m5.108-3.497a2.548 2.548 0 113.586 3.586l-6.837 5.63m-5.108 3.497l2.496-3.03c.317-.384.74-.626 1.208-.766M15.75 9.25a2.548 2.548 0 11-5.096 0 2.548 2.548 0 015.096 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M11.42 15.17L17.25 21A2.652 2.652 0 0021 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 11-3.586-3.586l6.837-5.63m5.108-3.497a2.548 2.548 0 113.586 3.586l-6.837 5.63m-5.108 3.497l2.496-3.03c.317-.384.74-.626 1.208-.766M15.75 9.25a2.548 2.548 0 11-5.096 0 2.548 2.548 0 015.096 0z" />
|
||||||
@@ -57,74 +62,63 @@ pub fn Setup() -> impl IntoView {
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="font-semibold tracking-tight text-2xl">"VibeTorrent Kurulumu"</h3>
|
<h3 class="font-semibold tracking-tight text-2xl">"VibeTorrent Kurulumu"</h3>
|
||||||
<p class="text-sm text-muted-foreground">"Yönetici hesabınızı oluşturun"</p>
|
<p class="text-sm text-muted-foreground">"Yönetici hesabınızı oluşturun"</p>
|
||||||
</div>
|
</CardHeader>
|
||||||
|
|
||||||
<div class="p-6 pt-4">
|
<CardContent class="pt-4">
|
||||||
<form on:submit=handle_setup class="space-y-4">
|
<form on:submit=handle_setup class="space-y-4">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
<Label>"Yönetici Kullanıcı Adı"</Label>
|
||||||
"Yönetici Kullanıcı Adı"
|
<Input
|
||||||
</label>
|
input_type="text"
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="admin"
|
placeholder="admin"
|
||||||
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
value=MaybeProp::derive(move || Some(username.0.get()))
|
||||||
prop:value=move || username.0.get()
|
on_change=Callback::new(move |val: String| username.1.set(val))
|
||||||
on:input=move |ev| username.1.set(event_target_value(&ev))
|
disabled=Signal::derive(move || loading.0.get())
|
||||||
disabled=move || loading.0.get()
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
<Label>"Şifre"</Label>
|
||||||
"Şifre"
|
<Input
|
||||||
</label>
|
input_type="password"
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
placeholder="******"
|
placeholder="******"
|
||||||
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
value=MaybeProp::derive(move || Some(password.0.get()))
|
||||||
prop:value=move || password.0.get()
|
on_change=Callback::new(move |val: String| password.1.set(val))
|
||||||
on:input=move |ev| password.1.set(event_target_value(&ev))
|
disabled=Signal::derive(move || loading.0.get())
|
||||||
disabled=move || loading.0.get()
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
<Label>"Şifre Onay"</Label>
|
||||||
"Şifre Onay"
|
<Input
|
||||||
</label>
|
input_type="password"
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
placeholder="******"
|
placeholder="******"
|
||||||
class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
value=MaybeProp::derive(move || Some(confirm_password.0.get()))
|
||||||
prop:value=move || confirm_password.0.get()
|
on_change=Callback::new(move |val: String| confirm_password.1.set(val))
|
||||||
on:input=move |ev| confirm_password.1.set(event_target_value(&ev))
|
disabled=Signal::derive(move || loading.0.get())
|
||||||
disabled=move || loading.0.get()
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when=move || error.0.get().is_some() fallback=|| ()>
|
<Show when=move || error.0.get().is_some() fallback=|| ()>
|
||||||
<div class="rounded-md border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive dark:border-destructive dark:bg-destructive/50 dark:text-destructive-foreground">
|
<Alert variant=AlertVariant::Destructive>
|
||||||
<span>{move || error.0.get().unwrap_or_default()}</span>
|
<AlertDescription>
|
||||||
</div>
|
<span>{move || error.0.get().unwrap_or_default()}</span>
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<div class="pt-2">
|
<div class="pt-2">
|
||||||
<button
|
<Button
|
||||||
class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2 w-full"
|
class="w-full"
|
||||||
type="submit"
|
disabled=Signal::derive(move || loading.0.get())
|
||||||
disabled=move || loading.0.get()
|
|
||||||
>
|
>
|
||||||
<Show when=move || loading.0.get() fallback=|| "Kurulumu Tamamla">
|
<Show when=move || loading.0.get() fallback=|| "Kurulumu Tamamla">
|
||||||
<span class="animate-spin mr-2 h-4 w-4 border-2 border-current border-t-transparent rounded-full"></span>
|
<span class="animate-spin mr-2 h-4 w-4 border-2 border-current border-t-transparent rounded-full"></span>
|
||||||
"Kuruluyor..."
|
"Kuruluyor..."
|
||||||
</Show>
|
</Show>
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</CardContent>
|
||||||
</div>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,22 @@
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use shared::NotificationLevel;
|
use shared::NotificationLevel;
|
||||||
|
use leptos_shadcn_alert::{Alert, AlertVariant};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Toast Components - Shadcn Style
|
// Toast Components - Using ShadCN Alert
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/// Returns the Shadcn class for the notification level
|
fn level_to_variant(level: &NotificationLevel) -> AlertVariant {
|
||||||
fn get_toast_class(level: &NotificationLevel) -> &'static str {
|
|
||||||
match level {
|
match level {
|
||||||
NotificationLevel::Info => "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-4 shadow-lg transition-all bg-background text-foreground border-border",
|
NotificationLevel::Info => AlertVariant::Default,
|
||||||
NotificationLevel::Success => "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-4 shadow-lg transition-all bg-background text-foreground border-primary/50 text-primary",
|
NotificationLevel::Success => AlertVariant::Success,
|
||||||
NotificationLevel::Warning => "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-4 shadow-lg transition-all bg-yellow-50 dark:bg-yellow-900/20 text-yellow-600 dark:text-yellow-500 border-yellow-200 dark:border-yellow-900",
|
NotificationLevel::Warning => AlertVariant::Warning,
|
||||||
NotificationLevel::Error => "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-4 shadow-lg transition-all destructive group border-destructive bg-destructive text-destructive-foreground",
|
NotificationLevel::Error => AlertVariant::Destructive,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Individual toast item component
|
fn level_icon(level: &NotificationLevel) -> impl IntoView {
|
||||||
#[component]
|
match level {
|
||||||
fn ToastItem(
|
|
||||||
level: NotificationLevel,
|
|
||||||
message: String,
|
|
||||||
) -> impl IntoView {
|
|
||||||
let toast_class = get_toast_class(&level);
|
|
||||||
|
|
||||||
// Icons
|
|
||||||
let icon_svg = match level {
|
|
||||||
NotificationLevel::Info => view! {
|
NotificationLevel::Info => view! {
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 opacity-90">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 opacity-90">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
|
||||||
@@ -45,15 +37,25 @@ fn ToastItem(
|
|||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
|
||||||
</svg>
|
</svg>
|
||||||
}.into_any(),
|
}.into_any(),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Individual toast item component
|
||||||
|
#[component]
|
||||||
|
fn ToastItem(
|
||||||
|
level: NotificationLevel,
|
||||||
|
message: String,
|
||||||
|
) -> impl IntoView {
|
||||||
|
let variant = level_to_variant(&level);
|
||||||
|
let icon = level_icon(&level);
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class=toast_class>
|
<Alert variant=variant class="pointer-events-auto shadow-lg">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
{icon_svg}
|
{icon}
|
||||||
<div class="text-sm font-medium">{message}</div>
|
<div class="text-sm font-medium">{message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Alert>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos::html;
|
|
||||||
use leptos::task::spawn_local;
|
use leptos::task::spawn_local;
|
||||||
|
use leptos_shadcn_dialog::{Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter};
|
||||||
|
use leptos_shadcn_input::Input;
|
||||||
|
use leptos_shadcn_button::{Button, ButtonVariant};
|
||||||
|
use leptos_shadcn_alert::{Alert, AlertDescription, AlertVariant};
|
||||||
use crate::store::TorrentStore;
|
use crate::store::TorrentStore;
|
||||||
use crate::api;
|
use crate::api;
|
||||||
|
|
||||||
@@ -11,16 +14,10 @@ pub fn AddTorrentDialog(
|
|||||||
let store = use_context::<TorrentStore>().expect("TorrentStore not provided");
|
let store = use_context::<TorrentStore>().expect("TorrentStore not provided");
|
||||||
let notifications = store.notifications;
|
let notifications = store.notifications;
|
||||||
|
|
||||||
let dialog_ref = NodeRef::<html::Dialog>::new();
|
|
||||||
let uri = signal(String::new());
|
let uri = signal(String::new());
|
||||||
let is_loading = signal(false);
|
let is_loading = signal(false);
|
||||||
let error_msg = signal(Option::<String>::None);
|
let error_msg = signal(Option::<String>::None);
|
||||||
|
let is_open = signal(true);
|
||||||
Effect::new(move |_| {
|
|
||||||
if let Some(dialog) = dialog_ref.get() {
|
|
||||||
let _ = dialog.show_modal();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let handle_submit = move |ev: web_sys::SubmitEvent| {
|
let handle_submit = move |ev: web_sys::SubmitEvent| {
|
||||||
ev.prevent_default();
|
ev.prevent_default();
|
||||||
@@ -44,9 +41,7 @@ pub fn AddTorrentDialog(
|
|||||||
shared::NotificationLevel::Success,
|
shared::NotificationLevel::Success,
|
||||||
"Torrent başarıyla eklendi"
|
"Torrent başarıyla eklendi"
|
||||||
);
|
);
|
||||||
if let Some(dialog) = dialog_ref.get() {
|
is_open.1.set(false);
|
||||||
dialog.close();
|
|
||||||
}
|
|
||||||
on_close.run(());
|
on_close.run(());
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -58,51 +53,58 @@ pub fn AddTorrentDialog(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let handle_cancel = move |_| {
|
|
||||||
if let Some(dialog) = dialog_ref.get() {
|
|
||||||
dialog.close();
|
|
||||||
}
|
|
||||||
on_close.run(());
|
|
||||||
};
|
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<dialog node_ref=dialog_ref class="modal modal-bottom sm:modal-middle">
|
<Dialog
|
||||||
<div class="modal-box">
|
open=Signal::derive(move || is_open.0.get())
|
||||||
<h3 class="font-bold text-lg">"Add Torrent"</h3>
|
on_open_change=Callback::new(move |open: bool| {
|
||||||
<p class="py-4 text-sm opacity-70">"Enter a Magnet link or a .torrent file URL."</p>
|
is_open.1.set(open);
|
||||||
|
if !open {
|
||||||
|
on_close.run(());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
>
|
||||||
|
<DialogContent class="sm:max-w-[425px]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>"Add Torrent"</DialogTitle>
|
||||||
|
<DialogDescription>"Enter a Magnet link or a .torrent file URL."</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
<form on:submit=handle_submit>
|
<form on:submit=handle_submit class="space-y-4">
|
||||||
<div class="form-control w-full">
|
<Input
|
||||||
<input
|
input_type="text"
|
||||||
type="text"
|
placeholder="magnet:?xt=urn:btih:..."
|
||||||
placeholder="magnet:?xt=urn:btih:..."
|
value=MaybeProp::derive(move || Some(uri.0.get()))
|
||||||
class="input input-bordered w-full"
|
on_change=Callback::new(move |val: String| uri.1.set(val))
|
||||||
prop:value=move || uri.0.get()
|
disabled=Signal::derive(move || is_loading.0.get())
|
||||||
on:input=move |ev| uri.1.set(event_target_value(&ev))
|
/>
|
||||||
disabled=move || is_loading.0.get()
|
|
||||||
autofocus
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-action">
|
{move || error_msg.0.get().map(|msg| view! {
|
||||||
<button type="button" class="btn btn-ghost" on:click=handle_cancel>"Cancel"</button>
|
<Alert variant=AlertVariant::Destructive>
|
||||||
<button type="submit" class="btn btn-primary" disabled=move || is_loading.0.get()>
|
<AlertDescription>{msg}</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
})}
|
||||||
|
|
||||||
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
variant=ButtonVariant::Ghost
|
||||||
|
on_click=Callback::new(move |()| {
|
||||||
|
is_open.1.set(false);
|
||||||
|
on_close.run(());
|
||||||
|
})
|
||||||
|
>
|
||||||
|
"Cancel"
|
||||||
|
</Button>
|
||||||
|
<Button disabled=Signal::derive(move || is_loading.0.get())>
|
||||||
{move || if is_loading.0.get() {
|
{move || if is_loading.0.get() {
|
||||||
leptos::either::Either::Left(view! { <span class="loading loading-spinner"></span> "Adding..." })
|
leptos::either::Either::Left(view! { <span class="loading loading-spinner"></span> "Adding..." })
|
||||||
} else {
|
} else {
|
||||||
leptos::either::Either::Right(view! { "Add" })
|
leptos::either::Either::Right(view! { "Add" })
|
||||||
}}
|
}}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</DialogFooter>
|
||||||
</form>
|
</form>
|
||||||
|
</DialogContent>
|
||||||
{move || error_msg.0.get().map(|msg| view! {
|
</Dialog>
|
||||||
<div class="text-error text-sm mt-2">{msg}</div>
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<form method="dialog" class="modal-backdrop">
|
|
||||||
<button on:click=handle_cancel>"close"</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user