Fix icon sizing and category filter
All checks were successful
docker / build-and-push (push) Successful in 47s
All checks were successful
docker / build-and-push (push) Successful in 47s
This commit is contained in:
@@ -50,6 +50,14 @@ export default function App() {
|
||||
() => links.filter((l) => l.enabled && `${l.name} ${l.description} ${l.category}`.toLowerCase().includes(query.toLowerCase())),
|
||||
[links, query]
|
||||
);
|
||||
const categories = useMemo(() => {
|
||||
const base = ['All'];
|
||||
const visible = links
|
||||
.filter((link) => link.enabled)
|
||||
.map((link) => link.category)
|
||||
.filter((value, index, array) => value && array.indexOf(value) === index);
|
||||
return base.concat(visible.sort((a, b) => a.localeCompare(b)));
|
||||
}, [links]);
|
||||
|
||||
if (page === 'loading') return <Shell><Centered>Loading Jellomator...</Centered></Shell>;
|
||||
if (page === 'setup') return <SetupPage onDone={refresh} />;
|
||||
@@ -75,7 +83,16 @@ export default function App() {
|
||||
onSave={async (payload, file) => {
|
||||
const fd = toFormData(payload, file);
|
||||
const url = editing ? `/api/links/${editing.id}` : '/api/links';
|
||||
await api.request(url, { method: editing ? 'PATCH' : 'POST', body: fd });
|
||||
try {
|
||||
await api.request(url, { method: editing ? 'PATCH' : 'POST', body: fd });
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
if (message.includes('Link name already exists')) {
|
||||
alert('Link names must be unique.');
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
setEditing(null);
|
||||
await refresh();
|
||||
}}
|
||||
@@ -102,7 +119,7 @@ export default function App() {
|
||||
<div className="glass rounded-3xl p-4">
|
||||
<input className="input" placeholder="Search services" value={query} onChange={(e) => setQuery(e.target.value)} />
|
||||
<div className="mt-4 space-y-2 text-sm text-slate-400">
|
||||
{['All', 'Arr*', 'Downloads', 'Media', 'Requests'].map((category) => (
|
||||
{categories.map((category) => (
|
||||
<button
|
||||
key={category}
|
||||
type="button"
|
||||
@@ -188,8 +205,8 @@ function Card({ link }: { link: LinkItem }) {
|
||||
return (
|
||||
<a href={link.url} target="_blank" rel="noreferrer" className="glass block rounded-3xl p-5 transition hover:-translate-y-1">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="grid h-12 w-12 place-items-center overflow-hidden rounded-2xl bg-white/5">
|
||||
{link.icon_url ? <img src={link.icon_url} className="h-full w-full object-cover" alt="" /> : <span className="font-semibold text-accent-300">{link.name[0]}</span>}
|
||||
<div className="grid h-12 w-12 place-items-center overflow-hidden rounded-2xl bg-white/5 p-1">
|
||||
{link.icon_url ? <img src={link.icon_url} className="h-full w-full object-contain" alt="" /> : <span className="font-semibold text-accent-300">{link.name[0]}</span>}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -345,8 +362,8 @@ function AdminPage({
|
||||
<div className="text-sm text-slate-400">Live preview</div>
|
||||
<div className="mt-3 rounded-2xl border border-white/10 bg-white/5 p-4">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="grid h-12 w-12 place-items-center overflow-hidden rounded-2xl bg-white/5">
|
||||
{preview ? <img src={preview} className="h-full w-full object-cover" alt="" /> : <span className="font-semibold text-accent-300">{form.name ? form.name[0] : 'S'}</span>}
|
||||
<div className="grid h-12 w-12 place-items-center overflow-hidden rounded-2xl bg-white/5 p-1">
|
||||
{preview ? <img src={preview} className="h-full w-full object-contain" alt="" /> : <span className="font-semibold text-accent-300">{form.name ? form.name[0] : 'S'}</span>}
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-semibold">{form.name || 'Service name'}</div>
|
||||
|
||||
Reference in New Issue
Block a user