refactor(ui): mobil yerleşimi iyileştir ve taşmayı düzelt

- AppLayout başlığının mobil uyumluluğunu yeniden düzenle
- İkon tabanlı butonlar kullanarak mobil alan tasarrufu sağla
- TimerPage'de taşan metinler için truncate sınıfları ekle
- Torrent bilgileri için daha iyi duyarlı düzen yapısı oluştur
This commit is contained in:
2026-01-02 21:32:00 +03:00
parent 81e9fa8783
commit 07c9589a03
2 changed files with 50 additions and 49 deletions

View File

@@ -8,7 +8,7 @@ import { useAppStore } from "../../store/useAppStore";
import { connectSocket } from "../../socket/socket"; import { connectSocket } from "../../socket/socket";
import { api } from "../../api/client"; import { api } from "../../api/client";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMoon, faSun } from "@fortawesome/free-solid-svg-icons"; import { faMoon, faSun, faRightFromBracket } from "@fortawesome/free-solid-svg-icons";
import { AlertToastStack } from "../ui/AlertToastStack"; import { AlertToastStack } from "../ui/AlertToastStack";
export const AppLayout = ({ children }: { children: React.ReactNode }) => { export const AppLayout = ({ children }: { children: React.ReactNode }) => {
@@ -65,12 +65,20 @@ export const AppLayout = ({ children }: { children: React.ReactNode }) => {
return ( return (
<Shell> <Shell>
<header className="rounded-xl border border-slate-200 bg-white/80 px-4 py-3"> <header className="rounded-xl border border-slate-200 bg-white/80 px-4 py-3">
<div className="flex items-start justify-between gap-3 md:items-center"> <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
<div> <div>
<div className="text-lg font-semibold text-slate-900">q-buffer</div> <div className="text-lg font-semibold text-slate-900">q-buffer</div>
<div className="text-xs text-slate-500"> <div className="text-xs text-slate-500">
qBittorrent {qbit.version ?? "unknown"} qBittorrent {qbit.version ?? "unknown"}
</div> </div>
<div className="mt-2 flex flex-wrap items-center gap-2">
<Badge variant={qbit.ok ? "success" : "danger"}>
{qbit.ok ? "Qbit OK" : "Qbit Down"}
</Badge>
<Badge variant={connected ? "success" : "warn"}>
{connected ? "Live" : "Offline"}
</Badge>
</div>
</div> </div>
<button <button
className="inline-flex items-center justify-center rounded-md border border-slate-300 px-3 py-2 text-xs font-semibold text-slate-700 md:hidden" className="inline-flex items-center justify-center rounded-md border border-slate-300 px-3 py-2 text-xs font-semibold text-slate-700 md:hidden"
@@ -79,53 +87,44 @@ export const AppLayout = ({ children }: { children: React.ReactNode }) => {
> >
{menuOpen ? "Close" : "Menu"} {menuOpen ? "Close" : "Menu"}
</button> </button>
</div> <div
<div className={`flex flex-col gap-3 md:flex md:flex-row md:items-center ${
className={`mt-3 flex flex-col gap-3 md:mt-0 md:flex md:flex-row md:items-center md:justify-between ${ menuOpen ? "flex" : "hidden md:flex"
menuOpen ? "flex" : "hidden md:flex" }`}
}`} >
> <nav className="flex flex-wrap items-center gap-2 rounded-full bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-600">
<nav className="flex flex-wrap items-center gap-2 rounded-full bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-600 md:justify-start"> <NavLink
<NavLink to="/buffer"
to="/buffer" className={({ isActive }) =>
className={({ isActive }) => `rounded-full px-3 py-1 ${
`rounded-full px-3 py-1 ${ isActive ? "bg-slate-900 text-white" : "hover:bg-white"
isActive ? "bg-slate-900 text-white" : "hover:bg-white" }`
}` }
} >
> Buffer
Buffer </NavLink>
</NavLink> <NavLink
<NavLink to="/timer"
to="/timer" className={({ isActive }) =>
className={({ isActive }) => `rounded-full px-3 py-1 ${
`rounded-full px-3 py-1 ${ isActive ? "bg-slate-900 text-white" : "hover:bg-white"
isActive ? "bg-slate-900 text-white" : "hover:bg-white" }`
}` }
} >
> Timer
Timer </NavLink>
</NavLink> </nav>
</nav>
<div className="flex flex-wrap items-center gap-2">
<Badge variant={qbit.ok ? "success" : "danger"}>
{qbit.ok ? "Qbit OK" : "Qbit Down"}
</Badge>
<Badge variant={connected ? "success" : "warn"}>
{connected ? "Live" : "Offline"}
</Badge>
<Button <Button
variant="outline" variant="outline"
onClick={() => applyTheme(theme === "dark" ? "light" : "dark")} onClick={() => applyTheme(theme === "dark" ? "light" : "dark")}
title={theme === "dark" ? "Light" : "Dark"}
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={theme === "dark" ? faSun : faMoon} icon={theme === "dark" ? faSun : faMoon}
className="mr-2"
/> />
{theme === "dark" ? "Light" : "Dark"}
</Button> </Button>
<Button variant="outline" onClick={logout}> <Button variant="outline" onClick={logout} title="Logout">
Logout <FontAwesomeIcon icon={faRightFromBracket} />
</Button> </Button>
</div> </div>
</div> </div>

View File

@@ -292,34 +292,36 @@ export const TimerPage = () => {
className="rounded-lg border border-slate-200 bg-white px-3 py-2" className="rounded-lg border border-slate-200 bg-white px-3 py-2"
> >
<div className="flex items-start justify-between gap-3"> <div className="flex items-start justify-between gap-3">
<div> <div className="min-w-0 flex-1">
<div <div
className="text-sm font-semibold text-slate-900" className="truncate text-sm font-semibold text-slate-900"
title={torrent.name} title={torrent.name}
> >
{torrent.name} {torrent.name}
</div> </div>
<div className="text-xs text-slate-500"> <div className="truncate text-xs text-slate-500">
{formatBytes(torrent.size)} {trackerLabel(torrent.tracker)} {formatBytes(torrent.size)} {trackerLabel(torrent.tracker)}
</div> </div>
</div> </div>
<div className="text-right text-xs text-slate-600"> <div className="w-24 flex-shrink-0 text-right text-xs text-slate-600">
<div className="font-semibold text-slate-900"> <div className="font-semibold text-slate-900">
{formatCountdown(remainingSeconds)} {formatCountdown(remainingSeconds)}
</div> </div>
<div>Kural: {formatDuration(rule.seedLimitSeconds)}</div> <div>Kural: {formatDuration(rule.seedLimitSeconds)}</div>
</div> </div>
</div> </div>
<div className="mt-2 flex flex-wrap gap-2 text-xs text-slate-600"> <div className="mt-2 grid grid-cols-2 gap-2 text-xs text-slate-600">
<span>Hash: {torrent.hash.slice(0, 12)}...</span> <div className="truncate">
<span> Hash: {torrent.hash.slice(0, 12)}...
</div>
<div className="truncate">
Etiket:{" "} Etiket:{" "}
{(torrent.tags || torrent.category || "-") {(torrent.tags || torrent.category || "-")
.split(",") .split(",")
.map((tag) => tag.trim()) .map((tag) => tag.trim())
.filter(Boolean) .filter(Boolean)
.join(", ") || "-"} .join(", ") || "-"}
</span> </div>
</div> </div>
</div> </div>
))} ))}