)}
{filteredSuggestions.length > 0 && (
-
+
{filteredSuggestions.map((tag, idx) => (
- {
onAddTag(tag.id);
setInput("");
@@ -101,10 +107,12 @@ const TagAutocompleteInput = forwardRef setAutocompleteIndex(idx)}
>
- #{tag.name}
- {tag.mandatory && (
- !
- )}
+
))}
diff --git a/frontend/src/pages/ItemsPage.tsx b/frontend/src/pages/ItemsPage.tsx
index 5f011a2..76397d4 100644
--- a/frontend/src/pages/ItemsPage.tsx
+++ b/frontend/src/pages/ItemsPage.tsx
@@ -12,7 +12,7 @@ import {
} from "../api";
import ItemList from "../components/ItemList";
import TagFilter from "../components/TagFilter";
-import { getTagColor } from "../utils/tagColors";
+import Tag from "../components/Tag";
async function fetchTrips(): Promise<{ id: string; name: string }[]> {
const res = await fetch("http://localhost:8000/trips/");
@@ -287,18 +287,12 @@ export default function ItemsPage() {
{!newItemTripId && (
{tags.map((tag) => (
- toggleNewItemTag(tag.id)}
- title={tag.mandatory ? "Pflicht-Tag (mandatory)" : ""}
- >
- #{tag.name}
- {tag.mandatory && !}
-
+ tag={tag}
+ isMarked={newItemTags.includes(tag.id)}
+ onToggleMark={toggleNewItemTag}
+ />
))}
)}
diff --git a/frontend/src/pages/TagsPage.tsx b/frontend/src/pages/TagsPage.tsx
index bedd395..803da6d 100644
--- a/frontend/src/pages/TagsPage.tsx
+++ b/frontend/src/pages/TagsPage.tsx
@@ -1,12 +1,11 @@
import React, { useEffect, useState } from "react";
import { getTags } from "../api";
-import type { Tag } from "../api";
-import { getTagColor } from "../utils/tagColors";
+import Tag from "../components/Tag";
const API_BASE = "http://localhost:8000";
export default function TagsPage() {
- const [tags, setTags] = useState([]);
+ const [tags, setTags] = useState([]);
const [editingId, setEditingId] = useState(null);
const [editName, setEditName] = useState("");
const [editMandatory, setEditMandatory] = useState(false);
@@ -15,7 +14,6 @@ export default function TagsPage() {
async function loadTags() {
const loaded = await getTags();
- // Alphabetisch sortieren
setTags(loaded.sort((a, b) => a.name.localeCompare(b.name)));
}
@@ -128,20 +126,14 @@ export default function TagsPage() {
className="flex items-center group"
style={{ marginBottom: "0.5rem" }}
>
- {
setEditingId(tag.id);
setEditName(tag.name);
setEditMandatory(tag.mandatory);
}}
- title="Bearbeiten"
- >
- #{tag.name}
- {tag.mandatory && !}
-
+ />
)
)}
diff --git a/frontend/src/pages/TripChecklist.tsx b/frontend/src/pages/TripChecklist.tsx
index 6580823..d44c32c 100644
--- a/frontend/src/pages/TripChecklist.tsx
+++ b/frontend/src/pages/TripChecklist.tsx
@@ -3,7 +3,8 @@ import React, { useState, useEffect, useRef } from "react";
import { useParams } from "react-router-dom";
import { getTripItems, toggleTripItem, updateTrip, getTags } from "../api";
import TagAutocompleteInput from "../components/TagAutocompleteInput";
-import { getTagColor } from "../utils/tagColors";
+import TripTag from "../components/Tag";
+import Tag from "../components/Tag";
export default function TripChecklist({ trips }: { trips: any[] }) {
const { id } = useParams();
@@ -282,36 +283,18 @@ export default function TripChecklist({ trips }: { trips: any[] }) {
{selectedTags.length === 0 ? (
keine
) : (
- selectedTags.map((tag: any) => {
- const isMarked = markedTags.some((mt: any) => mt.id === tag.id);
- const color = getTagColor(tag.id);
- return (
- handleToggleMark(tag.id)}
- onMouseEnter={() => setHoveredTag(tag.id)}
- onMouseLeave={() => setHoveredTag(null)}
- >
- #{tag.name}
- {tag.mandatory && !}
- {hoveredTag === tag.id && (
-
- )}
-
- );
- })
+ selectedTags.map((tag: any) => (
+ mt.id === tag.id)}
+ hoveredTag={hoveredTag}
+ onToggleMark={handleToggleMark}
+ onRemoveTag={handleRemoveTag}
+ onMouseEnter={setHoveredTag}
+ onMouseLeave={() => setHoveredTag(null)}
+ />
+ ))
)}
{/* "+Tag" link and dropdown */}
{!addingTag ? (