feat(spa): comment field in queue review, date picker in log sheet
All checks were successful
CI / Check / Test (push) Successful in 17m20s

This commit is contained in:
2026-06-04 22:35:30 +02:00
parent 237f1e7d32
commit 6a10ba15c1
3 changed files with 46 additions and 3 deletions

View File

@@ -1,9 +1,13 @@
import { useState } from "react"
import { useTranslation } from "react-i18next"
import { VisuallyHidden } from "radix-ui"
import { CalendarIcon } from "lucide-react"
import { format } from "date-fns"
import { Drawer, DrawerContent, DrawerTitle } from "@/components/ui/drawer"
import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Calendar } from "@/components/ui/calendar"
import { StarRating } from "@/components/star-rating"
import { SearchOverlay } from "@/components/search-overlay"
import type { MovieSelection } from "@/components/search-overlay"
@@ -22,12 +26,14 @@ export function LogSheet({ open, onOpenChange }: LogSheetProps) {
const [movie, setMovie] = useState<MovieSelection | null>(null)
const [rating, setRating] = useState(0)
const [comment, setComment] = useState("")
const [watchedAt, setWatchedAt] = useState<Date>(new Date())
const logMutation = useLogReview()
function reset() {
setMovie(null)
setRating(0)
setComment("")
setWatchedAt(new Date())
}
function handleClose() {
@@ -45,7 +51,7 @@ export function LogSheet({ open, onOpenChange }: LogSheetProps) {
manual_director: movie.director,
rating,
comment: comment || undefined,
watched_at: new Date().toISOString().replace("Z", "").split(".")[0]!,
watched_at: watchedAt.toISOString().replace("Z", "").split(".")[0]!,
},
{
onSuccess: () => {
@@ -86,6 +92,28 @@ export function LogSheet({ open, onOpenChange }: LogSheetProps) {
<Textarea value={comment} onChange={(e) => setComment(e.target.value)} placeholder={t("logReview.commentPlaceholder")} className="mb-5" rows={3} />
<div className="mb-5">
<p className="mb-2 text-xs uppercase tracking-wide text-muted-foreground">{t("logReview.watchedAt")}</p>
<Popover modal>
<PopoverTrigger asChild>
<Button variant="outline" className="w-full justify-start text-left font-normal">
<CalendarIcon className="mr-2 size-4" />
{format(watchedAt, "PPP")}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
fixedWeeks
selected={watchedAt}
onSelect={(d) => d && setWatchedAt(d)}
disabled={(d) => d > new Date()}
autoFocus
/>
</PopoverContent>
</Popover>
</div>
<Button onClick={handleSubmit} disabled={!rating || logMutation.isPending} className="w-full" size="lg">
{logMutation.isPending ? t("logReview.logging") : t("logReview.logReview")}
</Button>

View File

@@ -274,7 +274,9 @@
"commentPlaceholder": "Add a comment... (optional)",
"logging": "Logging...",
"logReview": "Log Review",
"logged": "{{title}} logged!"
"logged": "{{title}} logged!",
"watchedAt": "Watched on",
"pickDate": "Pick a date"
},
"searchOverlay": {
"backToSearch": "Back to search",

View File

@@ -11,6 +11,7 @@ import { VirtualList } from "@/components/virtual-list"
import { Button } from "@/components/ui/button"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Skeleton } from "@/components/ui/skeleton"
import { Textarea } from "@/components/ui/textarea"
import { StarRating } from "@/components/star-rating"
import { useAuth } from "@/components/auth-provider"
import { useQueryClient } from "@tanstack/react-query"
@@ -204,6 +205,7 @@ function QueueTab() {
const confirmMutation = useConfirmWatch()
const dismissMutation = useDismissWatch()
const [ratings, setRatings] = useState<Record<string, number>>({})
const [comments, setComments] = useState<Record<string, string>>({})
if (isPending) return <FeedSkeleton />
if (!data?.length)
@@ -224,13 +226,24 @@ function QueueTab() {
size="sm"
/>
</div>
<Textarea
className="mt-2"
placeholder={t("diary.commentPlaceholder")}
value={comments[entry.id] ?? ""}
onChange={(e) => setComments((p) => ({ ...p, [entry.id]: e.target.value }))}
rows={2}
/>
<div className="mt-2 flex gap-2">
<Button
size="sm"
disabled={!ratings[entry.id]}
onClick={() =>
confirmMutation.mutate({
confirmations: [{ watch_event_id: entry.id, rating: ratings[entry.id]! }],
confirmations: [{
watch_event_id: entry.id,
rating: ratings[entry.id]!,
comment: comments[entry.id] || undefined,
}],
})
}
>