mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +00:00
refactor(sns): use shared jump date popover
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React, { useEffect, useRef, useState } from 'react'
|
||||||
import { Search, Calendar, User, X, Loader2 } from 'lucide-react'
|
import { Search, Calendar, User, X, Loader2 } from 'lucide-react'
|
||||||
import { Avatar } from '../Avatar'
|
import { Avatar } from '../Avatar'
|
||||||
// import JumpToDateDialog from '../JumpToDateDialog' // Assuming this is imported from parent or moved
|
import JumpToDatePopover from '../JumpToDatePopover'
|
||||||
|
|
||||||
interface Contact {
|
interface Contact {
|
||||||
username: string
|
username: string
|
||||||
@@ -22,7 +22,6 @@ interface SnsFilterPanelProps {
|
|||||||
setSearchKeyword: (val: string) => void
|
setSearchKeyword: (val: string) => void
|
||||||
jumpTargetDate?: Date
|
jumpTargetDate?: Date
|
||||||
setJumpTargetDate: (date?: Date) => void
|
setJumpTargetDate: (date?: Date) => void
|
||||||
onOpenJumpDialog: () => void
|
|
||||||
selectedUsernames: string[]
|
selectedUsernames: string[]
|
||||||
setSelectedUsernames: (val: string[]) => void
|
setSelectedUsernames: (val: string[]) => void
|
||||||
contacts: Contact[]
|
contacts: Contact[]
|
||||||
@@ -37,7 +36,6 @@ export const SnsFilterPanel: React.FC<SnsFilterPanelProps> = ({
|
|||||||
setSearchKeyword,
|
setSearchKeyword,
|
||||||
jumpTargetDate,
|
jumpTargetDate,
|
||||||
setJumpTargetDate,
|
setJumpTargetDate,
|
||||||
onOpenJumpDialog,
|
|
||||||
selectedUsernames,
|
selectedUsernames,
|
||||||
setSelectedUsernames,
|
setSelectedUsernames,
|
||||||
contacts,
|
contacts,
|
||||||
@@ -46,6 +44,19 @@ export const SnsFilterPanel: React.FC<SnsFilterPanelProps> = ({
|
|||||||
loading,
|
loading,
|
||||||
contactsCountProgress
|
contactsCountProgress
|
||||||
}) => {
|
}) => {
|
||||||
|
const [showJumpPopover, setShowJumpPopover] = useState(false)
|
||||||
|
const jumpCalendarWrapRef = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!showJumpPopover) return
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (!jumpCalendarWrapRef.current) return
|
||||||
|
if (jumpCalendarWrapRef.current.contains(event.target as Node)) return
|
||||||
|
setShowJumpPopover(false)
|
||||||
|
}
|
||||||
|
document.addEventListener('mousedown', handleClickOutside)
|
||||||
|
return () => document.removeEventListener('mousedown', handleClickOutside)
|
||||||
|
}, [showJumpPopover])
|
||||||
|
|
||||||
const filteredContacts = contacts.filter(c =>
|
const filteredContacts = contacts.filter(c =>
|
||||||
(c.displayName || '').toLowerCase().includes(contactSearch.toLowerCase()) ||
|
(c.displayName || '').toLowerCase().includes(contactSearch.toLowerCase()) ||
|
||||||
@@ -116,27 +127,35 @@ export const SnsFilterPanel: React.FC<SnsFilterPanelProps> = ({
|
|||||||
<Calendar size={14} />
|
<Calendar size={14} />
|
||||||
<span>时间跳转</span>
|
<span>时间跳转</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="jump-calendar-anchor" ref={jumpCalendarWrapRef}>
|
||||||
className={`date-picker-trigger ${jumpTargetDate ? 'active' : ''}`}
|
<button
|
||||||
onClick={onOpenJumpDialog}
|
className={`date-picker-trigger ${jumpTargetDate ? 'active' : ''}`}
|
||||||
>
|
onClick={() => setShowJumpPopover(prev => !prev)}
|
||||||
<span className="date-text">
|
>
|
||||||
{jumpTargetDate
|
<span className="date-text">
|
||||||
? jumpTargetDate.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' })
|
{jumpTargetDate
|
||||||
: '选择日期...'}
|
? jumpTargetDate.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' })
|
||||||
</span>
|
: '选择日期...'}
|
||||||
{jumpTargetDate && (
|
</span>
|
||||||
<div
|
{jumpTargetDate && (
|
||||||
className="clear-date-btn"
|
<div
|
||||||
onClick={(e) => {
|
className="clear-date-btn"
|
||||||
e.stopPropagation()
|
onClick={(e) => {
|
||||||
setJumpTargetDate(undefined)
|
e.stopPropagation()
|
||||||
}}
|
setJumpTargetDate(undefined)
|
||||||
>
|
}}
|
||||||
<X size={12} />
|
>
|
||||||
</div>
|
<X size={12} />
|
||||||
)}
|
</div>
|
||||||
</button>
|
)}
|
||||||
|
</button>
|
||||||
|
<JumpToDatePopover
|
||||||
|
isOpen={showJumpPopover}
|
||||||
|
currentDate={jumpTargetDate || new Date()}
|
||||||
|
onClose={() => setShowJumpPopover(false)}
|
||||||
|
onSelect={(date) => setJumpTargetDate(date)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Contact Widget */}
|
{/* Contact Widget */}
|
||||||
|
|||||||
@@ -1063,6 +1063,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Date Widget */
|
/* Date Widget */
|
||||||
|
.jump-calendar-anchor {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
isolation: isolate;
|
||||||
|
z-index: 20;
|
||||||
|
|
||||||
|
.jump-date-popover {
|
||||||
|
z-index: 2600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.date-picker-trigger {
|
.date-picker-trigger {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from 'react'
|
import { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from 'react'
|
||||||
import { RefreshCw, Search, X, Download, FolderOpen, FileJson, FileText, Image, CheckCircle, AlertCircle, Calendar, Users, Info, ChevronLeft, ChevronRight, Shield, ShieldOff, Loader2 } from 'lucide-react'
|
import { RefreshCw, Search, X, Download, FolderOpen, FileJson, FileText, Image, CheckCircle, AlertCircle, Calendar, Users, Info, ChevronLeft, ChevronRight, Shield, ShieldOff, Loader2 } from 'lucide-react'
|
||||||
import JumpToDateDialog from '../components/JumpToDateDialog'
|
|
||||||
import './SnsPage.scss'
|
import './SnsPage.scss'
|
||||||
import { SnsPost } from '../types/sns'
|
import { SnsPost } from '../types/sns'
|
||||||
import { SnsPostItem } from '../components/Sns/SnsPostItem'
|
import { SnsPostItem } from '../components/Sns/SnsPostItem'
|
||||||
@@ -118,7 +117,6 @@ export default function SnsPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// UI states
|
// UI states
|
||||||
const [showJumpDialog, setShowJumpDialog] = useState(false)
|
|
||||||
const [debugPost, setDebugPost] = useState<SnsPost | null>(null)
|
const [debugPost, setDebugPost] = useState<SnsPost | null>(null)
|
||||||
const [authorTimelineTarget, setAuthorTimelineTarget] = useState<ContactSnsTimelineTarget | null>(null)
|
const [authorTimelineTarget, setAuthorTimelineTarget] = useState<ContactSnsTimelineTarget | null>(null)
|
||||||
|
|
||||||
@@ -1114,7 +1112,6 @@ export default function SnsPage() {
|
|||||||
setSearchKeyword={setSearchKeyword}
|
setSearchKeyword={setSearchKeyword}
|
||||||
jumpTargetDate={jumpTargetDate}
|
jumpTargetDate={jumpTargetDate}
|
||||||
setJumpTargetDate={setJumpTargetDate}
|
setJumpTargetDate={setJumpTargetDate}
|
||||||
onOpenJumpDialog={() => setShowJumpDialog(true)}
|
|
||||||
selectedUsernames={selectedUsernames}
|
selectedUsernames={selectedUsernames}
|
||||||
setSelectedUsernames={setSelectedUsernames}
|
setSelectedUsernames={setSelectedUsernames}
|
||||||
contacts={contacts}
|
contacts={contacts}
|
||||||
@@ -1125,16 +1122,6 @@ export default function SnsPage() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Dialogs and Overlays */}
|
{/* Dialogs and Overlays */}
|
||||||
<JumpToDateDialog
|
|
||||||
isOpen={showJumpDialog}
|
|
||||||
onClose={() => setShowJumpDialog(false)}
|
|
||||||
onSelect={(date) => {
|
|
||||||
setJumpTargetDate(date)
|
|
||||||
setShowJumpDialog(false)
|
|
||||||
}}
|
|
||||||
currentDate={jumpTargetDate || new Date()}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ContactSnsTimelineDialog
|
<ContactSnsTimelineDialog
|
||||||
target={authorTimelineTarget}
|
target={authorTimelineTarget}
|
||||||
onClose={closeAuthorTimeline}
|
onClose={closeAuthorTimeline}
|
||||||
|
|||||||
Reference in New Issue
Block a user