Add delete button to taste profile tags in Stats
- Backend: DELETE /stats/taste/{tag} removes the row from user_tag_affinity
- API: deleteTasteTag(tag) helper
- Stats UI: × button on each tag chip, faint by default, full opacity on hover;
invalidates stats query so the tag disappears immediately
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -129,6 +129,7 @@ export const getCommunityShelf = () => api.get("/discovery/community");
|
||||
|
||||
// Stats
|
||||
export const getStats = () => api.get("/stats");
|
||||
export const deleteTasteTag = (tag) => api.delete(`/stats/taste/${encodeURIComponent(tag)}`);
|
||||
|
||||
// Admin
|
||||
export const getAdminUsers = () => api.get("/admin/users");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getStats } from "../api";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { getStats, deleteTasteTag } from "../api";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function fmt(seconds) {
|
||||
@@ -22,12 +22,18 @@ function StatCard({ label, value, sub }) {
|
||||
}
|
||||
|
||||
export default function Stats() {
|
||||
const qc = useQueryClient();
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["stats"],
|
||||
queryFn: () => getStats().then(r => r.data),
|
||||
staleTime: 5 * 60_000,
|
||||
});
|
||||
|
||||
const deleteTag = useMutation({
|
||||
mutationFn: (tag) => deleteTasteTag(tag),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ["stats"] }),
|
||||
});
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-24">
|
||||
@@ -178,7 +184,7 @@ export default function Stats() {
|
||||
<span
|
||||
key={t.tag}
|
||||
title={`score: ${t.score.toFixed(1)}`}
|
||||
className="px-3 py-1 rounded-full text-xs font-medium"
|
||||
className="flex items-center gap-1 px-3 py-1 rounded-full text-xs font-medium"
|
||||
style={{
|
||||
backgroundColor: `rgba(250,204,21,${0.08 + intensity * 0.18})`,
|
||||
color: `hsl(50,95%,${55 + intensity * 20}%)`,
|
||||
@@ -186,6 +192,14 @@ export default function Stats() {
|
||||
}}
|
||||
>
|
||||
{t.tag}
|
||||
<button
|
||||
onClick={() => deleteTag.mutate(t.tag)}
|
||||
disabled={deleteTag.isPending}
|
||||
className="opacity-40 hover:opacity-100 transition-opacity leading-none ml-0.5"
|
||||
title="Remove from taste profile"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user