mirror of
https://github.com/Mail-0/Zero.git
synced 2026-06-28 14:56:48 +00:00
fit the design better
This commit is contained in:
@@ -83,7 +83,7 @@ function ComposeTabContent({
|
||||
// Update the tab with the new draft ID
|
||||
updateTab({ id: tabId, updates: { draftId: newDraftId } });
|
||||
}}
|
||||
className="h-full"
|
||||
className="h-full overflow-hidden rounded-2xl border-[1px] border-[#313131] bg-[#313131]"
|
||||
autofocus={true}
|
||||
settingsLoading={settingsLoading}
|
||||
isFullscreen={isFullscreen}
|
||||
@@ -215,7 +215,7 @@ export function ComposeTabs() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fixed bottom-4 right-4 z-40 flex max-w-[calc(100vw-32px)] flex-row-reverse items-end gap-3">
|
||||
<div className="fixed bottom-4 right-4 z-40 flex flex-row-reverse items-end gap-3 overflow-y-scroll">
|
||||
<AnimatePresence>
|
||||
{Array.from(composeTabs.values()).map((tab) => {
|
||||
const index = Array.from(composeTabs.values()).indexOf(tab);
|
||||
@@ -230,7 +230,7 @@ export function ComposeTabs() {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
y: 0,
|
||||
width: tab.isMinimized ? 'auto' : '450px',
|
||||
width: tab.isMinimized ? 'auto' : '500px',
|
||||
height: tab.isMinimized ? 'auto' : '600px',
|
||||
}}
|
||||
exit={{ opacity: 0, scale: 0.8, y: 20 }}
|
||||
@@ -248,7 +248,7 @@ export function ComposeTabs() {
|
||||
className={
|
||||
tab.isMinimized
|
||||
? 'cursor-pointer'
|
||||
: 'bg-background overflow-hidden rounded-lg border shadow-2xl'
|
||||
: 'bg-background overflow-hidden rounded-2xl border shadow-2xl dark:bg-[#313131]'
|
||||
}
|
||||
>
|
||||
<AnimatePresence mode="wait">
|
||||
@@ -259,7 +259,7 @@ export function ComposeTabs() {
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.15 }}
|
||||
className="hover:bg-accent flex h-10 items-center gap-2 rounded-lg border bg-[#FFFFFF] px-4 py-2 shadow-lg dark:bg-[#202020]"
|
||||
className="hover:bg-accent flex h-10 items-center gap-2 rounded-2xl border bg-[#FFFFFF] py-2 pl-4 pr-2.5 shadow-lg dark:bg-[#313131]"
|
||||
onClick={() => toggleMinimize(tab.id)}
|
||||
>
|
||||
<span className="text-sm font-medium">
|
||||
@@ -290,7 +290,7 @@ export function ComposeTabs() {
|
||||
className="flex h-full flex-col"
|
||||
onClick={() => setActiveTabId(tab.id)}
|
||||
>
|
||||
<div className="dark:bg-panelDark flex items-center justify-between border-b p-2 pr-1.5">
|
||||
<div className="flex items-center justify-between border-b bg-white p-2 px-3 pr-1.5 dark:bg-[#313131]">
|
||||
<h3 className="text-sm font-medium">{tab.subject || 'New Email'}</h3>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
@@ -323,7 +323,7 @@ export function ComposeTabs() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dark:bg-panelDark flex-1 overflow-y-auto">
|
||||
<div className="flex-1 overflow-y-auto dark:bg-[#313131]">
|
||||
<ComposeTabContent
|
||||
tab={tab}
|
||||
tabId={tab.id}
|
||||
@@ -340,7 +340,7 @@ export function ComposeTabs() {
|
||||
);
|
||||
})}
|
||||
</AnimatePresence>
|
||||
|
||||
{/*
|
||||
<motion.div initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }}>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -350,7 +350,7 @@ export function ComposeTabs() {
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
</Button>
|
||||
</motion.div>
|
||||
</motion.div> */}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -93,6 +93,18 @@ interface EmailComposerProps {
|
||||
isFullscreen?: boolean;
|
||||
}
|
||||
|
||||
type FormData = {
|
||||
to: string[];
|
||||
subject: string;
|
||||
message: string;
|
||||
attachments?: File[];
|
||||
headers?: any;
|
||||
cc?: string[];
|
||||
bcc?: string[];
|
||||
threadId?: string;
|
||||
fromEmail?: string;
|
||||
};
|
||||
|
||||
const schema = z.object({
|
||||
to: z.array(z.string().email()).min(1),
|
||||
subject: z.string().min(1),
|
||||
@@ -234,7 +246,7 @@ function EmailComposerBase({
|
||||
trpc.ai.generateEmailSubject.mutationOptions(),
|
||||
);
|
||||
|
||||
const form = useForm<z.infer<typeof schema>>({
|
||||
const form = useForm<FormData>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
to: initialTo,
|
||||
@@ -542,9 +554,19 @@ function EmailComposerBase({
|
||||
};
|
||||
|
||||
// Debounced onChange to prevent excessive re-renders
|
||||
const debouncedOnChange = useDebounce((updates: any) => {
|
||||
onChange?.(updates);
|
||||
}, 500);
|
||||
const debouncedOnChange = useDebounce(
|
||||
(updates: {
|
||||
to?: string[];
|
||||
cc?: string[];
|
||||
bcc?: string[];
|
||||
subject?: string;
|
||||
body?: string;
|
||||
attachments?: File[];
|
||||
}) => {
|
||||
onChange?.(updates);
|
||||
},
|
||||
500,
|
||||
);
|
||||
|
||||
// Add useEffect to notify parent of changes
|
||||
useEffect(() => {
|
||||
@@ -669,18 +691,16 @@ function EmailComposerBase({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex max-h-dvh w-full flex-col overflow-hidden bg-[#FAFAFA] shadow-sm dark:bg-[#202020]',
|
||||
'flex max-h-dvh w-full flex-col overflow-hidden rounded-none bg-[#FAFAFA] shadow-sm dark:bg-[#313131]',
|
||||
{
|
||||
'rounded-2xl': !inATab,
|
||||
'rounded-none': inATab,
|
||||
'max-w-[750px]': !isFullscreen,
|
||||
},
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className="no-scrollbar dark:bg-panelDark relative flex min-h-0 flex-1 flex-col overflow-y-auto">
|
||||
<div className="no-scrollbar relative flex min-h-0 flex-1 flex-col overflow-y-auto rounded-b-2xl border dark:bg-[#313131]">
|
||||
{/* To, Cc, Bcc */}
|
||||
<div className="shrink-0 overflow-visible border-b border-[#E7E7E7] pb-2 dark:border-[#252525]">
|
||||
<div className="shrink-0 overflow-y-auto border-b border-t border-[#E7E7E7] pb-2 dark:border-[#3B3B3B]">
|
||||
<div className="flex justify-between px-3 pt-3">
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<p className="text-sm font-medium text-[#8C8C8C]">To:</p>
|
||||
@@ -811,7 +831,7 @@ function EmailComposerBase({
|
||||
|
||||
<Toolbar editor={editor} />
|
||||
|
||||
<div className="absolute bottom-1 left-3 z-10">
|
||||
<div className="absolute bottom-3 left-3 z-10">
|
||||
<AnimatePresence>
|
||||
{aiGeneratedMessage !== null ? (
|
||||
<ContentPreview
|
||||
@@ -863,7 +883,7 @@ function EmailComposerBase({
|
||||
</div>
|
||||
|
||||
{/* Message Content */}
|
||||
<div className="flex-1 overflow-y-auto bg-[#FFFFFF] outline-white/5 dark:bg-[#202020]">
|
||||
<div className="flex-1 overflow-y-auto rounded-b-2xl bg-[#FFFFFF] dark:bg-[#202020]">
|
||||
<div
|
||||
onClick={() => {
|
||||
editor.commands.focus();
|
||||
@@ -883,7 +903,7 @@ function EmailComposerBase({
|
||||
</div>
|
||||
|
||||
{/* Bottom Actions */}
|
||||
<div className="inline-flex w-full shrink-0 items-end justify-between self-stretch rounded-b-2xl bg-[#FFFFFF] px-3 py-3 outline-white/5 dark:bg-[#202020]">
|
||||
<div className="inline-flex w-full shrink-0 items-end justify-between self-stretch rounded-b-2xl bg-[#FFFFFF] px-3 py-3 outline-white/5 dark:bg-[#313131]">
|
||||
<div className="flex flex-col items-start justify-start gap-2">
|
||||
<div className="flex items-center justify-start gap-2">
|
||||
<Button
|
||||
@@ -1293,7 +1313,7 @@ const ContentPreview = ({
|
||||
initial="initial"
|
||||
animate="animate"
|
||||
exit="exit"
|
||||
className="dark:bg-subtleBlack absolute bottom-full right-0 z-30 z-50 w-[400px] overflow-hidden rounded-xl border bg-white p-1 shadow-md"
|
||||
className="dark:bg-subtleBlack absolute bottom-full right-0 z-50 w-[400px] overflow-hidden rounded-xl border bg-white p-1 shadow-md"
|
||||
>
|
||||
<div
|
||||
className="max-h-60 min-h-[150px] overflow-auto rounded-md p-1 text-sm"
|
||||
|
||||
@@ -24,7 +24,7 @@ export const Toolbar = ({ editor }: { editor: Editor | null }) => {
|
||||
if (!editor) return null;
|
||||
|
||||
return (
|
||||
<div className="bg-panelDark flex w-full gap-2 border-b p-2 text-sm">
|
||||
<div className="flex w-full gap-2 rounded-t-2xl border-none bg-[#202020] p-2 text-sm">
|
||||
<TooltipProvider>
|
||||
<div className="control-group overflow-x-auto">
|
||||
<div className="button-group ml-0 flex flex-wrap gap-1">
|
||||
|
||||
@@ -255,10 +255,10 @@ export default function ReplyCompose({ messageId }: ReplyComposeProps) {
|
||||
if (!mode || !emailData) return null;
|
||||
|
||||
return (
|
||||
<div className="w-full rounded-2xl overflow-visible border">
|
||||
<div className="w-full overflow-visible rounded-2xl border">
|
||||
<EmailComposer
|
||||
editorClassName="min-h-[50px]"
|
||||
className="w-full max-w-none! pb-1 overflow-visible"
|
||||
editorClassName="min-h-[180px]"
|
||||
className="w-full !max-w-none overflow-hidden pb-1"
|
||||
onSendEmail={handleSendEmail}
|
||||
onClose={async () => {
|
||||
setMode(null);
|
||||
|
||||
Reference in New Issue
Block a user