v1.19: Schadensmeldungen mit Kommunikation verknuepft
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useSearchParams } from 'react-router'
|
||||
import { MailPlus, SendHorizonal, UserRound } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
@@ -68,6 +69,7 @@ function NewMessageDialog({ onCreated }: { onCreated: (id: string) => void }) {
|
||||
|
||||
export default function Messages() {
|
||||
const { threads, role, units, meineEinheit, markThreadRead, addMessage } = useStore()
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const visible = role === 'tenant'
|
||||
? threads.filter((t) => t.unitId === meineEinheit.id)
|
||||
: threads
|
||||
@@ -76,6 +78,19 @@ export default function Messages() {
|
||||
const [draft, setDraft] = useState('')
|
||||
const bottomRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
// Deep-Link aus anderen Modulen (z. B. Schadensmeldung): ?thread=<id>
|
||||
useEffect(() => {
|
||||
const gewuenscht = searchParams.get('thread')
|
||||
if (!gewuenscht) return
|
||||
const gefunden = visible.find((t) => t.id === gewuenscht)
|
||||
if (gefunden) {
|
||||
setActiveId(gefunden.id)
|
||||
searchParams.delete('thread')
|
||||
setSearchParams(searchParams, { replace: true })
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [threads, role])
|
||||
|
||||
useEffect(() => {
|
||||
if (!active) return
|
||||
markThreadRead(active.id)
|
||||
|
||||
+34
-2
@@ -1,5 +1,6 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import { Plus, Wrench, CalendarDays, MapPin } from 'lucide-react'
|
||||
import { Link } from 'react-router'
|
||||
import { Plus, Wrench, CalendarDays, MapPin, MessagesSquare } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import {
|
||||
@@ -141,9 +142,11 @@ function NewTicketDialog() {
|
||||
}
|
||||
|
||||
export default function Tickets() {
|
||||
const { tickets, units, role, setTicketStatus, meineEinheit } = useStore()
|
||||
const { tickets, units, role, setTicketStatus, meineEinheit, threads } = useStore()
|
||||
const [filter, setFilter] = useState<'alle' | TicketStatus>('alle')
|
||||
|
||||
const threadFuerTicket = (ticketId: string) => threads.find((th) => th.ticketId === ticketId)
|
||||
|
||||
const visible = useMemo(
|
||||
() =>
|
||||
(role === 'tenant'
|
||||
@@ -197,6 +200,8 @@ export default function Tickets() {
|
||||
<div className="space-y-3">
|
||||
{visible.map((t) => {
|
||||
const unit = units.find((u) => u.id === t.unitId)
|
||||
const thread = threadFuerTicket(t.id)
|
||||
const letzte = thread?.messages[thread.messages.length - 1]
|
||||
return (
|
||||
<div key={t.id} className="rounded-2xl border bg-white p-5 shadow-sm">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||
@@ -238,6 +243,33 @@ export default function Tickets() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{thread && (
|
||||
<div className="mt-4 rounded-xl border border-teal-100 bg-teal-50/60 p-4">
|
||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
||||
<div className="flex items-center gap-2 text-sm font-semibold text-teal-800">
|
||||
<MessagesSquare className="h-4 w-4" />
|
||||
Kommunikation
|
||||
<span className="text-xs font-normal text-teal-600">
|
||||
({thread.messages.length} {thread.messages.length === 1 ? 'Nachricht' : 'Nachrichten'})
|
||||
</span>
|
||||
</div>
|
||||
<Link
|
||||
to={`/nachrichten?thread=${thread.id}`}
|
||||
className="text-xs font-medium text-teal-700 underline-offset-2 hover:underline"
|
||||
>
|
||||
Unterhaltung öffnen →
|
||||
</Link>
|
||||
</div>
|
||||
{letzte && (
|
||||
<div className="mt-2 text-xs text-slate-600">
|
||||
<span className="font-semibold">{letzte.author}:</span>{' '}
|
||||
<span className="line-clamp-2">{letzte.text}</span>
|
||||
<span className="mt-0.5 block text-slate-400">{letzte.at}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -87,6 +87,8 @@ export interface Thread {
|
||||
subject: string
|
||||
unreadByTenant: boolean
|
||||
unreadByAdmin: boolean
|
||||
/** Verknüpfte Schadensmeldung (v1.19), null bei normalen Unterhaltungen */
|
||||
ticketId?: string | null
|
||||
messages: Message[]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user