- Inputs: uniform padding (8px 12px), borderRadius 7, bg-inset background - List rows/cards: bg-subtle background, border-subtle border (bg-inset was input-only) - Invite/admin badge borders: use accent-border var instead of raw accent - Section headers: 11px, weight 500, uppercase, 0.7px letter-spacing - Notification/status banners: borderRadius 8 - Remove debug console.log statements from SettingsPage avatar upload flow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
127 lines
4.1 KiB
TypeScript
127 lines
4.1 KiB
TypeScript
import { useState } from "react";
|
|
import { useNavigate, Navigate } from "react-router-dom";
|
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
import { listBands, createBand } from "../api/bands";
|
|
|
|
export function HomePage() {
|
|
const navigate = useNavigate();
|
|
const qc = useQueryClient();
|
|
const [name, setName] = useState("");
|
|
const [slug, setSlug] = useState("");
|
|
const [ncBasePath, setNcBasePath] = useState("");
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const { data: bands, isLoading } = useQuery({
|
|
queryKey: ["bands"],
|
|
queryFn: listBands,
|
|
});
|
|
|
|
const createMutation = useMutation({
|
|
mutationFn: () => createBand({ name, slug, ...(ncBasePath ? { nc_base_path: ncBasePath } : {}) }),
|
|
onSuccess: (band) => {
|
|
qc.invalidateQueries({ queryKey: ["bands"] });
|
|
navigate(`/bands/${band.id}`);
|
|
},
|
|
onError: (err) => setError(err instanceof Error ? err.message : "Failed to create band"),
|
|
});
|
|
|
|
// Redirect to the first band once bands are loaded
|
|
if (!isLoading && bands && bands.length > 0) {
|
|
return <Navigate to={`/bands/${bands[0].id}`} replace />;
|
|
}
|
|
|
|
const inputStyle: React.CSSProperties = {
|
|
width: "100%",
|
|
padding: "8px 12px",
|
|
background: "var(--bg-inset)",
|
|
border: "1px solid var(--border)",
|
|
borderRadius: 7,
|
|
color: "var(--text)",
|
|
marginBottom: 12,
|
|
fontSize: 14,
|
|
};
|
|
|
|
const labelStyle: React.CSSProperties = {
|
|
display: "block",
|
|
color: "var(--text-muted)",
|
|
fontSize: 11,
|
|
marginBottom: 6,
|
|
};
|
|
|
|
return (
|
|
<div style={{ padding: 32, maxWidth: 480, margin: "0 auto" }}>
|
|
{isLoading ? (
|
|
<p style={{ color: "var(--text-muted)" }}>Loading…</p>
|
|
) : (
|
|
<>
|
|
<h2 style={{ color: "var(--text)", margin: "0 0 8px", fontSize: 17, fontWeight: 500 }}>
|
|
Create your first band
|
|
</h2>
|
|
<p style={{ color: "var(--text-muted)", fontSize: 12, margin: "0 0 24px", lineHeight: 1.6 }}>
|
|
Give your band a name to get started. You can add members and connect storage after.
|
|
</p>
|
|
|
|
{error && (
|
|
<p style={{ color: "var(--danger)", fontSize: 13, marginBottom: 12 }}>{error}</p>
|
|
)}
|
|
|
|
<label style={labelStyle}>BAND NAME</label>
|
|
<input
|
|
value={name}
|
|
onChange={(e) => {
|
|
setName(e.target.value);
|
|
setSlug(
|
|
e.target.value
|
|
.toLowerCase()
|
|
.replace(/\s+/g, "-")
|
|
.replace(/[^a-z0-9-]/g, "")
|
|
);
|
|
}}
|
|
style={inputStyle}
|
|
autoFocus
|
|
/>
|
|
|
|
<label style={labelStyle}>SLUG</label>
|
|
<input
|
|
value={slug}
|
|
onChange={(e) => setSlug(e.target.value)}
|
|
style={{ ...inputStyle, fontFamily: "monospace", marginBottom: 16 }}
|
|
/>
|
|
|
|
<label style={labelStyle}>
|
|
NEXTCLOUD BASE FOLDER{" "}
|
|
<span style={{ color: "var(--text-subtle)" }}>(optional)</span>
|
|
</label>
|
|
<input
|
|
value={ncBasePath}
|
|
onChange={(e) => setNcBasePath(e.target.value)}
|
|
placeholder={`bands/${slug || "my-band"}/`}
|
|
style={{ ...inputStyle, fontSize: 13, fontFamily: "monospace", marginBottom: 4 }}
|
|
/>
|
|
<p style={{ color: "var(--text-subtle)", fontSize: 11, margin: "0 0 20px" }}>
|
|
Path relative to your Nextcloud root. Leave blank to use{" "}
|
|
<code style={{ color: "var(--text-muted)" }}>bands/{slug || "slug"}/</code>
|
|
</p>
|
|
|
|
<button
|
|
onClick={() => createMutation.mutate()}
|
|
disabled={!name || !slug || createMutation.isPending}
|
|
style={{
|
|
background: "var(--accent)",
|
|
border: "none",
|
|
borderRadius: 6,
|
|
color: "var(--accent-fg)",
|
|
cursor: "pointer",
|
|
padding: "9px 22px",
|
|
fontWeight: 600,
|
|
fontSize: 13,
|
|
}}
|
|
>
|
|
{createMutation.isPending ? "Creating…" : "Create Band"}
|
|
</button>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|