summaryrefslogtreecommitdiff
path: root/app/routes/band-new.tsx
diff options
context:
space:
mode:
authoryyamashita <yyamashita@mosquit.one>2026-05-09 00:51:08 +0900
committeryyamashita <yyamashita@mosquit.one>2026-05-09 00:51:08 +0900
commitb8548d029760ecfa59cafedd23899a91e6120b5f (patch)
tree681543d0acc26d6adc90bbe19493e50740505de3 /app/routes/band-new.tsx
parentd944f11581553c5e038b33fa4558566713f6d1f4 (diff)
Add predefined link types and artist roles
- app/lib/constants.ts: LINK_TYPES (12種) and ARTIST_ROLES (13種) - Band link forms: label input → type select (公式サイト, X, Instagram, ...) - Band member forms: role text → role select (Vocal, Guitar, Bass, ...) - Band detail: resolve link type key to display label via LINK_TYPE_LABEL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'app/routes/band-new.tsx')
-rw-r--r--app/routes/band-new.tsx25
1 files changed, 17 insertions, 8 deletions
diff --git a/app/routes/band-new.tsx b/app/routes/band-new.tsx
index b4d49e2..86222a3 100644
--- a/app/routes/band-new.tsx
+++ b/app/routes/band-new.tsx
@@ -2,6 +2,7 @@ import { useState } from "react";
import { Form, Link, redirect, useActionData, useLoaderData } from "react-router";
import type { ActionFunctionArgs } from "react-router";
import { createBand, getIpAddress, listArtists } from "~/lib/db.server";
+import { ARTIST_ROLES, LINK_TYPES } from "~/lib/constants";
export function loader() {
return { artists: listArtists() };
@@ -53,6 +54,7 @@ export default function BandNew() {
const [slug, setSlug] = useState("");
const [slugManual, setSlugManual] = useState(false);
const [links, setLinks] = useState<{ label: string; url: string }[]>([]);
+ const DEFAULT_LINK_TYPE = LINK_TYPES[0].value;
const [picked, setPicked] = useState<{ id: string; name: string; role: string }[]>([]);
const available = artists.filter((a) => !picked.some((p) => p.id === a.id));
@@ -136,12 +138,15 @@ export default function BandNew() {
<div className="space-y-2">
{links.map((link, i) => (
<div key={i} className="flex gap-2">
- <input
+ <select
value={link.label}
onChange={(e) => setLinks(links.map((l, idx) => idx === i ? { ...l, label: e.target.value } : l))}
- placeholder="ラベル (例: X)"
- className="w-28 bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500 text-sm"
- />
+ className="w-36 bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500 text-sm"
+ >
+ {LINK_TYPES.map((t) => (
+ <option key={t.value} value={t.value}>{t.label}</option>
+ ))}
+ </select>
<input
value={link.url}
onChange={(e) => setLinks(links.map((l, idx) => idx === i ? { ...l, url: e.target.value } : l))}
@@ -160,7 +165,7 @@ export default function BandNew() {
</div>
<button
type="button"
- onClick={() => setLinks([...links, { label: "", url: "" }])}
+ onClick={() => setLinks([...links, { label: DEFAULT_LINK_TYPE, url: "" }])}
className="mt-2 text-blue-400 hover:text-blue-300 text-sm transition-colors"
>
+ リンクを追加
@@ -173,12 +178,16 @@ export default function BandNew() {
{picked.map((p, i) => (
<div key={p.id} className="flex gap-2 items-center">
<span className="text-gray-200 text-sm w-32 truncate">{p.name}</span>
- <input
+ <select
value={p.role}
onChange={(e) => setPicked(picked.map((a, idx) => idx === i ? { ...a, role: e.target.value } : a))}
- placeholder="パート (例: Guitar)"
className="flex-1 bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500 text-sm"
- />
+ >
+ <option value="">— パートを選択 —</option>
+ {ARTIST_ROLES.map((r) => (
+ <option key={r} value={r}>{r}</option>
+ ))}
+ </select>
<button
type="button"
onClick={() => setPicked(picked.filter((_, idx) => idx !== i))}