feat: add frontend/src/store/mailStore.ts
This commit is contained in:
parent
1716c52354
commit
0237fe6604
75
frontend/src/store/mailStore.ts
Normal file
75
frontend/src/store/mailStore.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { create } from 'zustand'
|
||||||
|
import { persist } from 'zustand/middleware'
|
||||||
|
|
||||||
|
export interface Folder { name: string; display: string; unread: number; total: number }
|
||||||
|
export interface MailSummary {
|
||||||
|
uid: string; subject: string; sender: string; sender_addr: string
|
||||||
|
date: string; is_read: boolean; has_attachment: boolean; size: number; preview: string
|
||||||
|
}
|
||||||
|
export interface MailDetail extends MailSummary {
|
||||||
|
to: string; cc: string; body_text: string; body_html: string
|
||||||
|
attachments: { part_id: string; filename: string; content_type: string; size: number }[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MailStore {
|
||||||
|
token: string | null
|
||||||
|
username: string
|
||||||
|
displayName: string
|
||||||
|
folders: Folder[]
|
||||||
|
currentFolder: string
|
||||||
|
messages: MailSummary[]
|
||||||
|
totalMessages: number
|
||||||
|
currentPage: number
|
||||||
|
selectedMail: MailDetail | null
|
||||||
|
loading: boolean
|
||||||
|
searchQuery: string
|
||||||
|
composeOpen: boolean
|
||||||
|
replyTo: MailDetail | null
|
||||||
|
|
||||||
|
setToken: (token: string, username: string, displayName: string) => void
|
||||||
|
logout: () => void
|
||||||
|
setFolders: (f: Folder[]) => void
|
||||||
|
setCurrentFolder: (f: string) => void
|
||||||
|
setMessages: (m: MailSummary[], total: number, page: number) => void
|
||||||
|
setSelectedMail: (m: MailDetail | null) => void
|
||||||
|
setLoading: (v: boolean) => void
|
||||||
|
setSearchQuery: (q: string) => void
|
||||||
|
openCompose: (replyTo?: MailDetail | null) => void
|
||||||
|
closeCompose: () => void
|
||||||
|
markRead: (uid: string) => void
|
||||||
|
removeMessage: (uid: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useMailStore = create<MailStore>()(
|
||||||
|
persist(
|
||||||
|
(set) => ({
|
||||||
|
token: null, username: '', displayName: '',
|
||||||
|
folders: [], currentFolder: 'INBOX',
|
||||||
|
messages: [], totalMessages: 0, currentPage: 1,
|
||||||
|
selectedMail: null, loading: false,
|
||||||
|
searchQuery: '', composeOpen: false, replyTo: null,
|
||||||
|
|
||||||
|
setToken: (token, username, displayName) => set({ token, username, displayName }),
|
||||||
|
logout: () => set({ token: null, username: '', displayName: '', messages: [], selectedMail: null }),
|
||||||
|
setFolders: (folders) => set({ folders }),
|
||||||
|
setCurrentFolder: (currentFolder) => set({ currentFolder, messages: [], selectedMail: null, currentPage: 1 }),
|
||||||
|
setMessages: (messages, totalMessages, currentPage) => set({ messages, totalMessages, currentPage }),
|
||||||
|
setSelectedMail: (selectedMail) => set({ selectedMail }),
|
||||||
|
setLoading: (loading) => set({ loading }),
|
||||||
|
setSearchQuery: (searchQuery) => set({ searchQuery }),
|
||||||
|
openCompose: (replyTo = null) => set({ composeOpen: true, replyTo }),
|
||||||
|
closeCompose: () => set({ composeOpen: false, replyTo: null }),
|
||||||
|
markRead: (uid) => set(s => ({
|
||||||
|
messages: s.messages.map(m => m.uid === uid ? { ...m, is_read: true } : m),
|
||||||
|
folders: s.folders.map(f =>
|
||||||
|
f.name === s.currentFolder ? { ...f, unread: Math.max(0, f.unread - 1) } : f
|
||||||
|
),
|
||||||
|
})),
|
||||||
|
removeMessage: (uid) => set(s => ({
|
||||||
|
messages: s.messages.filter(m => m.uid !== uid),
|
||||||
|
selectedMail: s.selectedMail?.uid === uid ? null : s.selectedMail,
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
{ name: 'zioinfo-mail', partialize: s => ({ token: s.token, username: s.username, displayName: s.displayName }) }
|
||||||
|
)
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue
Block a user