feat: enhance TripChecklist to categorize items if they contain a '/'
This commit is contained in:
parent
9a55a994a3
commit
f390ce80d6
1 changed files with 70 additions and 3 deletions
|
|
@ -91,6 +91,22 @@ export default function TripChecklist({ trips }: { trips: any[] }) {
|
||||||
|
|
||||||
// Gruppiere Items nach Kategorie (item.tag)
|
// Gruppiere Items nach Kategorie (item.tag)
|
||||||
const itemsWithoutTag = items.filter((item) => !item.tag);
|
const itemsWithoutTag = items.filter((item) => !item.tag);
|
||||||
|
|
||||||
|
// Split items into "slash" category items and normal items
|
||||||
|
const slashCategoryMap: Record<string, any[]> = {};
|
||||||
|
const normalItemsWithoutTag: any[] = [];
|
||||||
|
|
||||||
|
itemsWithoutTag.forEach((item) => {
|
||||||
|
const name = item.name_calculated || "";
|
||||||
|
if (name.includes("/")) {
|
||||||
|
const [cat, sub] = name.split("/", 2);
|
||||||
|
if (!slashCategoryMap[cat]) slashCategoryMap[cat] = [];
|
||||||
|
slashCategoryMap[cat].push({ ...item, _sub: sub });
|
||||||
|
} else {
|
||||||
|
normalItemsWithoutTag.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Map: tagId -> { tag, items: [...] }
|
// Map: tagId -> { tag, items: [...] }
|
||||||
const itemsByTag: Record<string, { tag: any; items: any[] }> = {};
|
const itemsByTag: Record<string, { tag: any; items: any[] }> = {};
|
||||||
items
|
items
|
||||||
|
|
@ -203,8 +219,8 @@ export default function TripChecklist({ trips }: { trips: any[] }) {
|
||||||
</div>
|
</div>
|
||||||
{/* ...Rest der Checklist... */}
|
{/* ...Rest der Checklist... */}
|
||||||
<ul>
|
<ul>
|
||||||
{/* Einträge ohne Kategorie */}
|
{/* Einträge ohne Kategorie und ohne Slash */}
|
||||||
{itemsWithoutTag.map((item) => (
|
{normalItemsWithoutTag.map((item) => (
|
||||||
<li
|
<li
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className={
|
className={
|
||||||
|
|
@ -245,7 +261,7 @@ export default function TripChecklist({ trips }: { trips: any[] }) {
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* Einträge mit Kategorie */}
|
{/* Einträge mit Kategorie (item.tag) */}
|
||||||
{sortedTagGroups.map(({ tag, items }) => (
|
{sortedTagGroups.map(({ tag, items }) => (
|
||||||
<React.Fragment key={tag.id}>
|
<React.Fragment key={tag.id}>
|
||||||
<li className="mt-4 mb-1 font-semibold text-gray-700 flex items-center gap-2">
|
<li className="mt-4 mb-1 font-semibold text-gray-700 flex items-center gap-2">
|
||||||
|
|
@ -295,6 +311,57 @@ export default function TripChecklist({ trips }: { trips: any[] }) {
|
||||||
))}
|
))}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{/* Slash categories at the end */}
|
||||||
|
{Object.entries(slashCategoryMap).map(([cat, items]) => (
|
||||||
|
<React.Fragment key={cat}>
|
||||||
|
<li className="mt-6 mb-1 font-semibold text-gray-700 flex items-center gap-2">
|
||||||
|
<h3 className="text-m text-gray-700 px-2 py-0.5 m-0 font-semibold">
|
||||||
|
{cat.charAt(0).toUpperCase() + cat.slice(1)}
|
||||||
|
</h3>
|
||||||
|
</li>
|
||||||
|
{items.map((item) => (
|
||||||
|
<li
|
||||||
|
key={item.id}
|
||||||
|
className={
|
||||||
|
"flex items-center gap-2 cursor-pointer select-none px-2 py-1 rounded group " +
|
||||||
|
(item.checked ? "bg-green-100" : "hover:bg-gray-100")
|
||||||
|
}
|
||||||
|
onClick={async () => {
|
||||||
|
await toggleTripItem(item.id);
|
||||||
|
const updated = await getTripItems(id!);
|
||||||
|
setItems(updated);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={item.checked}
|
||||||
|
readOnly
|
||||||
|
tabIndex={-1}
|
||||||
|
className="pointer-events-none"
|
||||||
|
/>
|
||||||
|
<span className={item.checked ? "line-through text-gray-400" : ""}>
|
||||||
|
{item._sub}
|
||||||
|
</span>
|
||||||
|
{item.item && item.item.tags && item.item.tags.length > 0 && (
|
||||||
|
<span className="ml-2 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
|
{[...item.item.tags]
|
||||||
|
.slice()
|
||||||
|
.sort((a, b) => a.name.localeCompare(b.name))
|
||||||
|
.map((tag: any) => (
|
||||||
|
<span
|
||||||
|
key={tag.id}
|
||||||
|
className="text-xs text-gray-400 rounded px-1 py-0.5"
|
||||||
|
>
|
||||||
|
#{tag.name}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue