fix: mobile ticket view - internal notes toggle (publish=2), Mail icon for email notes, showInternal state
This commit is contained in:
parent
011ae559de
commit
8cd8a94412
1 changed files with 29 additions and 13 deletions
|
|
@ -4,7 +4,7 @@ import { useEffect, useState, use } from 'react';
|
|||
import { useRouter } from 'next/navigation';
|
||||
import {
|
||||
ArrowLeft, RefreshCw, Clock, FileText, Timer, CheckCircle2,
|
||||
ChevronDown, ChevronRight, User, Briefcase, AlertCircle, EyeOff, Eye,
|
||||
ChevronDown, ChevronRight, User, Briefcase, AlertCircle, EyeOff, Eye, Mail,
|
||||
} from 'lucide-react';
|
||||
|
||||
const PRIORITY_LABEL: Record<number, string> = {
|
||||
|
|
@ -162,17 +162,19 @@ function TimelineCard({ item, defaultOpen = false }: { item: TimelineItem; defau
|
|||
|
||||
// note
|
||||
const note = item.data;
|
||||
const isInternal = note.publish === 1;
|
||||
const isInternal = note.publish === 2;
|
||||
const isSystem = item.is_system;
|
||||
const bodyNodes = renderContent(note.description ?? '');
|
||||
const bodyPlain = (note.description ?? '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
|
||||
const iconColor = isSystem ? 'text-muted-foreground' : isInternal ? 'text-slate-400' : 'text-amber-500';
|
||||
const iconBg = isSystem ? 'bg-muted' : isInternal ? 'bg-muted' : 'bg-amber-500/10';
|
||||
const isEmail = note.note_type === 2;
|
||||
const iconColor = isSystem ? 'text-muted-foreground' : isInternal ? 'text-slate-400' : isEmail ? 'text-violet-500' : 'text-amber-500';
|
||||
const iconBg = isSystem ? 'bg-muted' : isInternal ? 'bg-muted' : isEmail ? 'bg-violet-500/10' : 'bg-amber-500/10';
|
||||
const NoteIcon = isEmail ? Mail : FileText;
|
||||
return (
|
||||
<div className="flex gap-3">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className={`w-8 h-8 rounded-full flex items-center justify-center shrink-0 ${iconBg}`}>
|
||||
<FileText className={`w-4 h-4 ${iconColor}`} />
|
||||
<NoteIcon className={`w-4 h-4 ${iconColor}`} />
|
||||
</div>
|
||||
<div className="w-px flex-1 bg-border mt-1" />
|
||||
</div>
|
||||
|
|
@ -209,6 +211,7 @@ export default function TicketTimeline({ params }: { params: Promise<{ id: strin
|
|||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [showSystem, setShowSystem] = useState(false);
|
||||
const [showInternal, setShowInternal] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
|
|
@ -280,20 +283,33 @@ export default function TicketTimeline({ params }: { params: Promise<{ id: strin
|
|||
|
||||
{/* Timeline */}
|
||||
<div className="px-4 pt-5">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center justify-between mb-4 gap-3">
|
||||
<p className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">Timeline</p>
|
||||
<button
|
||||
onClick={() => setShowSystem(s => !s)}
|
||||
className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors">
|
||||
{showSystem ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
|
||||
{showSystem ? 'Hide system' : 'Show system'}
|
||||
</button>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={() => setShowInternal(s => !s)}
|
||||
className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors">
|
||||
{showInternal ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
|
||||
{showInternal ? 'Hide internal' : 'Show internal'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowSystem(s => !s)}
|
||||
className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors">
|
||||
{showSystem ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
|
||||
{showSystem ? 'Hide system' : 'Show system'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{timeline.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground text-center py-8">No activity recorded</p>
|
||||
) : (
|
||||
timeline
|
||||
.filter(item => showSystem || item.kind !== 'note' || !item.is_system)
|
||||
.filter(item => {
|
||||
if (item.kind !== 'note') return true;
|
||||
if (!showSystem && item.is_system) return false;
|
||||
if (!showInternal && (item.data as any).publish === 2) return false;
|
||||
return true;
|
||||
})
|
||||
.map((item, i) => (
|
||||
<TimelineCard key={i} item={item} defaultOpen={item.kind === 'note' && i === timeline.length - 1} />
|
||||
))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue