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)
|
||||
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: [...] }
|
||||
const itemsByTag: Record<string, { tag: any; items: any[] }> = {};
|
||||
items
|
||||
|
|
@ -203,8 +219,8 @@ export default function TripChecklist({ trips }: { trips: any[] }) {
|
|||
</div>
|
||||
{/* ...Rest der Checklist... */}
|
||||
<ul>
|
||||
{/* Einträge ohne Kategorie */}
|
||||
{itemsWithoutTag.map((item) => (
|
||||
{/* Einträge ohne Kategorie und ohne Slash */}
|
||||
{normalItemsWithoutTag.map((item) => (
|
||||
<li
|
||||
key={item.id}
|
||||
className={
|
||||
|
|
@ -245,7 +261,7 @@ export default function TripChecklist({ trips }: { trips: any[] }) {
|
|||
</li>
|
||||
))}
|
||||
|
||||
{/* Einträge mit Kategorie */}
|
||||
{/* Einträge mit Kategorie (item.tag) */}
|
||||
{sortedTagGroups.map(({ tag, items }) => (
|
||||
<React.Fragment key={tag.id}>
|
||||
<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>
|
||||
))}
|
||||
|
||||
{/* 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>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue