solve mail backend 12
This commit is contained in:
parent
a2ef35aa29
commit
9f8c28238b
1364
app/mail/page.tsx
1364
app/mail/page.tsx
File diff suppressed because it is too large
Load Diff
14
app/types/mail.ts
Normal file
14
app/types/mail.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export interface Mail {
|
||||||
|
id: string;
|
||||||
|
from: string;
|
||||||
|
subject: string;
|
||||||
|
body: string;
|
||||||
|
date: string;
|
||||||
|
read: boolean;
|
||||||
|
starred: boolean;
|
||||||
|
attachments?: {
|
||||||
|
filename: string;
|
||||||
|
size: number;
|
||||||
|
type: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
@ -1,11 +1,13 @@
|
|||||||
import { Mail } from '@/hooks/use-mail';
|
import { Mail } from "@/types/mail";
|
||||||
|
import { Star, StarOff, Paperclip } from "lucide-react";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
|
||||||
interface MailListProps {
|
interface MailListProps {
|
||||||
mails: Mail[];
|
mails: Mail[];
|
||||||
onMailClick?: (mail: Mail) => void;
|
onMailClick: (mail: Mail) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MailList = ({ mails = [], onMailClick }: MailListProps) => {
|
export function MailList({ mails, onMailClick }: MailListProps) {
|
||||||
if (!mails || mails.length === 0) {
|
if (!mails || mails.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center h-64">
|
<div className="flex items-center justify-center h-64">
|
||||||
@ -15,30 +17,43 @@ export const MailList = ({ mails = [], onMailClick }: MailListProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col space-y-2">
|
<div className="flex-1 overflow-auto">
|
||||||
{mails.map((mail) => (
|
{mails.map((mail) => (
|
||||||
<div
|
<div
|
||||||
key={mail.id}
|
key={mail.id}
|
||||||
className={`p-4 border rounded-lg cursor-pointer hover:bg-gray-50 ${
|
className={`p-4 border-b cursor-pointer hover:bg-muted ${
|
||||||
!mail.read ? 'font-semibold' : ''
|
!mail.read ? "bg-muted/50" : ""
|
||||||
}`}
|
}`}
|
||||||
onClick={() => onMailClick?.(mail)}
|
onClick={() => onMailClick(mail)}
|
||||||
>
|
>
|
||||||
<div className="flex justify-between items-start">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex-1">
|
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="text-sm text-gray-600">{mail.from}</span>
|
{mail.starred ? (
|
||||||
{mail.starred && (
|
<Star className="h-4 w-4 text-yellow-400" />
|
||||||
<span className="text-yellow-400">★</span>
|
) : (
|
||||||
|
<StarOff className="h-4 w-4 text-muted-foreground" />
|
||||||
)}
|
)}
|
||||||
|
<span className="font-medium">{mail.from}</span>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-lg font-medium">{mail.subject}</h3>
|
<span className="text-sm text-muted-foreground">
|
||||||
<p className="text-sm text-gray-500 truncate">{mail.body}</p>
|
{format(new Date(mail.date), "MMM d, yyyy")}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-400">{new Date(mail.date).toLocaleDateString()}</span>
|
<div className="mt-2">
|
||||||
|
<h3 className="font-medium">{mail.subject}</h3>
|
||||||
|
<p className="text-sm text-muted-foreground line-clamp-2">
|
||||||
|
{mail.body}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
{mail.attachments && mail.attachments.length > 0 && (
|
||||||
|
<div className="mt-2 flex items-center text-sm text-muted-foreground">
|
||||||
|
<Paperclip className="h-3 w-3 mr-1" />
|
||||||
|
{mail.attachments.length} attachment
|
||||||
|
{mail.attachments.length > 1 ? "s" : ""}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Search } from "lucide-react";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { RefreshCw, Plus, Search } from "lucide-react";
|
||||||
|
|
||||||
interface MailToolbarProps {
|
interface MailToolbarProps {
|
||||||
onRefresh: () => void;
|
onRefresh: () => void;
|
||||||
@ -11,15 +11,16 @@ interface MailToolbarProps {
|
|||||||
export function MailToolbar({ onRefresh, onCompose, onSearch }: MailToolbarProps) {
|
export function MailToolbar({ onRefresh, onCompose, onSearch }: MailToolbarProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between p-4 border-b">
|
<div className="flex items-center justify-between p-4 border-b">
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center space-x-2">
|
||||||
<Button variant="outline" onClick={onRefresh}>
|
<Button variant="ghost" size="icon" onClick={onRefresh}>
|
||||||
Refresh
|
<RefreshCw className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" onClick={onCompose}>
|
<Button onClick={onCompose}>
|
||||||
|
<Plus className="h-4 w-4 mr-2" />
|
||||||
Compose
|
Compose
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 max-w-md">
|
<div className="flex-1 max-w-md mx-4">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@ -1,19 +1,7 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
|
import type { Mail } from '@/types/mail';
|
||||||
|
|
||||||
export interface Mail {
|
export type { Mail };
|
||||||
id: string;
|
|
||||||
from: string;
|
|
||||||
to: string;
|
|
||||||
subject: string;
|
|
||||||
body: string;
|
|
||||||
date: string;
|
|
||||||
read: boolean;
|
|
||||||
starred: boolean;
|
|
||||||
folder: string;
|
|
||||||
cc?: string[];
|
|
||||||
bcc?: string[];
|
|
||||||
flags?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useMail = () => {
|
export const useMail = () => {
|
||||||
const [mails, setMails] = useState<Mail[]>([]);
|
const [mails, setMails] = useState<Mail[]>([]);
|
||||||
|
|||||||
14
types/mail.ts
Normal file
14
types/mail.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export interface Mail {
|
||||||
|
id: string;
|
||||||
|
from: string;
|
||||||
|
to: string;
|
||||||
|
subject: string;
|
||||||
|
body: string;
|
||||||
|
date: string;
|
||||||
|
read: boolean;
|
||||||
|
starred: boolean;
|
||||||
|
folder: string;
|
||||||
|
cc?: string[];
|
||||||
|
bcc?: string[];
|
||||||
|
flags?: string[];
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user