Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"lint:fix": "oxlint --fix",
"fmt": "oxfmt",
"fmt:check": "oxfmt --check",
"preinstall": "npx only-allow pnpm"
"preinstall": "npx only-allow pnpm",
"supabase": "supabase"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
Expand Down Expand Up @@ -41,13 +42,11 @@
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@radix-ui/react-visually-hidden": "^1.2.4",
"@supabase/ssr": "^0.8.0",
"@supabase/supabase-js": "^2.95.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"input-otp": "^1.4.2",
"lucide-react": "^0.562.0",
Expand Down
28 changes: 0 additions & 28 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
packages:
- .

minimumReleaseAge: 10080
trustPolicy: no-downgrade

ignoredBuiltDependencies:
- sharp
- unrs-resolver
Expand Down
2 changes: 1 addition & 1 deletion src/features/admin/items/ui/item-delete-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function ItemDeleteDialog({ open, item, onOpenChange }: ItemDeleteDialogP

{errorMessage ? (
<p className="flex items-center justify-center gap-1 text-sm text-red-600">
<AlertCircle className="h-4 w-4" />
<AlertCircle className="size-4" />
{errorMessage}
</p>
) : null}
Expand Down
6 changes: 3 additions & 3 deletions src/features/admin/items/ui/item-form-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function FieldError({ message }: { message?: string }) {

return (
<p className="mt-1 flex items-center gap-1 text-xs text-red-600">
<AlertCircle className="h-3.5 w-3.5" />
<AlertCircle className="size-3.5" />
{message}
</p>
);
Expand Down Expand Up @@ -98,7 +98,7 @@ export function ItemFormDialog({ mode, open, item, onOpenChange }: ItemFormDialo
<form onSubmit={handleSubmit} className="space-y-5">
<section>
<h3 className="mb-3 flex items-center gap-2 text-sm font-semibold">
<Package className="h-4 w-4" />
<Package className="size-4" />
物品情報
</h3>

Expand All @@ -118,7 +118,7 @@ export function ItemFormDialog({ mode, open, item, onOpenChange }: ItemFormDialo

{submitError ? (
<p className="flex items-center gap-1 text-sm text-red-600">
<AlertCircle className="h-4 w-4" />
<AlertCircle className="size-4" />
{submitError}
</p>
) : null}
Expand Down
2 changes: 1 addition & 1 deletion src/features/admin/items/ui/item-list-page-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function ItemListPageView({ items }: ItemListPageViewProps) {
className="bg-zinc-950 text-white hover:bg-zinc-800"
onClick={() => setCreateOpen(true)}
>
<CirclePlus className="h-4 w-4" />
<CirclePlus className="size-4" />
物品を追加
</Button>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/features/admin/items/ui/item-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function ItemTable({ items, onEdit, onDelete }: ItemTableProps) {
onClick={() => onEdit(item)}
aria-label="編集"
>
<Pencil className="h-4 w-4 text-green-600" aria-hidden="true" />
<Pencil className="size-4 text-green-600" aria-hidden="true" />
</Button>
</TableCell>
<TableCell className="px-2 text-center">
Expand All @@ -72,7 +72,7 @@ export function ItemTable({ items, onEdit, onDelete }: ItemTableProps) {
onClick={() => onDelete(item)}
aria-label="削除"
>
<Trash2 className="h-4 w-4 text-red-600" aria-hidden="true" />
<Trash2 className="size-4 text-red-600" aria-hidden="true" />
</Button>
</TableCell>
</TableRow>
Expand Down
2 changes: 1 addition & 1 deletion src/features/admin/locations/ui/location-delete-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function LocationDeleteDialog({ open, location, onOpenChange }: LocationD

{errorMessage ? (
<p className="flex items-center justify-center gap-1 text-sm text-[#c91111]">
<AlertCircle className="h-4 w-4" />
<AlertCircle className="size-4" />
{errorMessage}
</p>
) : null}
Expand Down
4 changes: 2 additions & 2 deletions src/features/admin/locations/ui/location-form-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function FieldError({ message }: { message?: string }) {

return (
<p role="alert" aria-live="polite" className="flex items-center gap-1 text-xs text-[#c91111]">
<AlertCircle className="h-3.5 w-3.5" />
<AlertCircle className="size-3.5" />
{message}
</p>
);
Expand Down Expand Up @@ -182,7 +182,7 @@ export function LocationFormDialog({
aria-live="polite"
className="flex items-center justify-center gap-1 px-9 pb-5 text-sm text-[#c91111]"
>
<AlertCircle className="h-4 w-4" />
<AlertCircle className="size-4" />
{submitError}
</p>
) : null}
Expand Down
16 changes: 8 additions & 8 deletions src/features/admin/locations/ui/location-list-page-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,17 @@ export function LocationListPageView({ locations }: LocationListPageViewProps) {
const [dialogState, dispatchDialog] = useReducer(dialogReducer, initialDialogState);

return (
<main className="px-6 py-6 md:px-16 md:py-8">
<div className="mx-auto max-w-[876px] space-y-4">
<main className="min-h-[calc(100vh-60px)] bg-[#f3f4f6] px-6 py-8 md:px-16">
<div className="mx-auto flex max-w-[876px] flex-col gap-4">
<h1 className="sr-only">場所一覧</h1>

<div className="flex justify-end">
<Button
type="button"
className="h-[52px] rounded-[10px] bg-zinc-950 px-4 text-sm font-normal text-white hover:bg-zinc-800"
className="bg-zinc-950 text-white hover:bg-zinc-800"
onClick={() => dispatchDialog({ type: "open-create-root" })}
>
<CirclePlus className="h-4 w-4" />
<CirclePlus className="size-4" />
エリアを追加
</Button>
</div>
Expand All @@ -87,20 +87,20 @@ export function LocationListPageView({ locations }: LocationListPageViewProps) {
type="button"
variant="outline"
size="sm"
className="h-8 rounded-[10px] border-zinc-300 bg-white px-3 text-xs font-normal text-zinc-700"
className="h-8 rounded-[10px] border-[#e5e7eb] bg-white px-3 text-xs font-normal text-black shadow-[0_1px_1px_rgba(0,0,0,0.25)] hover:bg-white/90"
onClick={() => setExpandedIds(new Set(expandableIds))}
>
<UnfoldVertical className="h-3.5 w-3.5" />
<UnfoldVertical className="size-3" />
全て展開
</Button>
<Button
type="button"
variant="outline"
size="sm"
className="h-8 rounded-[10px] border-zinc-300 bg-white px-3 text-xs font-normal text-zinc-700"
className="h-8 rounded-[10px] border-[#e5e7eb] bg-white px-3 text-xs font-normal text-black shadow-[0_1px_1px_rgba(0,0,0,0.25)] hover:bg-white/90"
onClick={() => setExpandedIds(new Set())}
>
<FoldVertical className="h-3.5 w-3.5" />
<FoldVertical className="size-3" />
折りたたむ
</Button>
</div>
Expand Down
73 changes: 33 additions & 40 deletions src/features/admin/locations/ui/location-tree.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { ChevronRight, Pencil, Plus, Trash2 } from "lucide-react";
import { ChevronDown, ChevronRight, Pencil, Plus, Trash2 } from "lucide-react";
import type { CSSProperties } from "react";
import { Button } from "@/components/ui/button";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { cn } from "@/lib/utils";
Expand All @@ -17,71 +18,57 @@ type LocationTreeProps = {

type LocationTreeNodeProps = Omit<LocationTreeProps, "locations"> & {
location: AdminLocation;
isNested?: boolean;
};

type LocationTreeLineStyle = CSSProperties & {
"--location-tree-line-left": string;
};

function canCreateChild(location: AdminLocation) {
return location.depth < 2;
}

function rowBackgroundClass(hasChildren: boolean, isExpanded: boolean) {
if (hasChildren && isExpanded) {
return "bg-[#f3f4f6]";
}

return "bg-transparent";
}

function LocationTreeNode({
location,
expandedIds,
onExpandedChange,
onCreateChild,
onEdit,
onDelete,
isNested = false,
}: LocationTreeNodeProps) {
const hasChildren = location.children.length > 0;
const isExpanded = hasChildren ? expandedIds.has(location.locationId) : false;
const indent = location.depth * 56;

return (
<div className={cn("relative", isNested && "pl-8")}>
<div className="relative">
<Collapsible
open={isExpanded}
onOpenChange={(open) => onExpandedChange(location.locationId, open)}
>
<div
className={cn(
"flex min-h-14 items-center justify-between border-b px-4 py-1 transition-colors duration-200 ease-out motion-reduce:transition-none",
location.depth === 0 ? "border-black" : "border-zinc-300",
rowBackgroundClass(hasChildren, isExpanded),
)}
className="flex min-h-14 items-center justify-between rounded-lg border-b border-[#e5e5e5] bg-white px-4 py-1 transition-colors duration-200 ease-out motion-reduce:transition-none"
style={{ marginLeft: indent }}
>
<div className="min-w-0 flex-1">
{hasChildren ? (
<CollapsibleTrigger asChild>
<button
type="button"
className="group flex min-h-11 items-center gap-3 text-left text-[18px] font-normal text-[#0a0a0a] outline-none focus-visible:ring-2 focus-visible:ring-zinc-400"
className="group flex min-h-11 items-center gap-2 text-left text-[20px] leading-5 font-normal text-[#0a0a0a] outline-none focus-visible:ring-2 focus-visible:ring-zinc-400"
>
<span
className={cn(
"flex size-7 shrink-0 items-center justify-center rounded-full transition-colors duration-200 ease-out motion-reduce:transition-none",
isExpanded ? "bg-black/5" : "bg-transparent group-hover:bg-black/5",
<span className="flex size-4 shrink-0 items-center justify-center">
{isExpanded ? (
<ChevronDown className="size-4 shrink-0" />
) : (
<ChevronRight className="size-4 shrink-0" />
)}
>
<ChevronRight
className={cn(
"h-4 w-4 shrink-0 transition-transform duration-300 ease-out motion-reduce:transition-none",
isExpanded && "rotate-90",
)}
/>
</span>
<span className="truncate">{location.name}</span>
</button>
</CollapsibleTrigger>
) : (
<div className="flex min-h-11 items-center gap-3 pl-7 text-[18px] font-normal text-[#0a0a0a]">
<div className="flex min-h-11 items-center text-[20px] leading-5 font-normal text-[#0a0a0a]">
<span className="truncate">{location.name}</span>
</div>
)}
Expand All @@ -93,34 +80,34 @@ function LocationTreeNode({
type="button"
variant="ghost"
size="icon-sm"
className="h-11 w-11 rounded-md text-black transition-colors duration-200 hover:bg-black/5"
className="size-12 rounded-md text-black transition-colors duration-200 hover:bg-black/5"
aria-label={`${location.name}の配下に場所を追加`}
onClick={() => onCreateChild(location)}
>
<Plus className="h-5 w-5" />
<Plus className="size-5" />
</Button>
) : (
<div className="w-11" aria-hidden="true" />
<div className="w-12" aria-hidden="true" />
)}
<Button
type="button"
variant="ghost"
size="icon-sm"
className="h-11 w-11 rounded-md transition-colors duration-200 hover:bg-black/5"
className="size-12 rounded-md transition-colors duration-200 hover:bg-black/5"
aria-label={`${location.name}を編集`}
onClick={() => onEdit(location)}
>
<Pencil className="h-5 w-5 text-[#70b64d]" />
<Pencil className="size-5 text-[#70b64d]" />
</Button>
<Button
type="button"
variant="ghost"
size="icon-sm"
className="h-11 w-11 rounded-md transition-colors duration-200 hover:bg-black/5"
className="size-12 rounded-md transition-colors duration-200 hover:bg-black/5"
aria-label={`${location.name}を削除`}
onClick={() => onDelete(location)}
>
<Trash2 className="h-5 w-5 text-[#ff1f1f]" />
<Trash2 className="size-5 text-[#ff1f1f]" />
</Button>
</div>
</div>
Expand All @@ -134,7 +121,14 @@ function LocationTreeNode({
"data-[state=open]:slide-in-from-top-1 data-[state=closed]:slide-out-to-top-1",
)}
>
<div className="ml-6 border-l border-zinc-300">
<div
className={cn(
"relative",
isExpanded &&
"before:absolute before:top-3 before:bottom-3 before:left-[var(--location-tree-line-left)] before:w-px before:bg-[#d1d5db]",
)}
style={{ "--location-tree-line-left": `${indent + 24}px` } as LocationTreeLineStyle}
>
{location.children.map((child) => (
<LocationTreeNode
key={child.locationId}
Expand All @@ -144,7 +138,6 @@ function LocationTreeNode({
onCreateChild={onCreateChild}
onEdit={onEdit}
onDelete={onDelete}
isNested
/>
))}
</div>
Expand All @@ -164,7 +157,7 @@ export function LocationTree({
onDelete,
}: LocationTreeProps) {
return (
<div className="space-y-0">
<div>
{locations.map((location) => (
<LocationTreeNode
key={location.locationId}
Expand Down
Loading
Loading