docs: adding mail example (#389)

This commit is contained in:
Saeid Zareie 2024-03-07 16:52:39 +03:30 committed by GitHub
parent e817da4b8b
commit d832e9f48a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 1015 additions and 9 deletions

View File

@ -8,6 +8,11 @@ import ArrowRightIcon from '~icons/radix-icons/arrow-right'
const { path } = toRefs(useRoute()) const { path } = toRefs(useRoute())
const examples = [ const examples = [
{
name: 'Mail',
href: '/examples/mail',
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/mail',
},
{ {
name: 'Dashboard', name: 'Dashboard',
href: '/examples/dashboard', href: '/examples/dashboard',
@ -58,7 +63,7 @@ const currentExample = computed(() => examples.find(ex => path.value.startsWith(
:href="example.href" :href="example.href"
:class="cn( :class="cn(
'flex items-center px-4', 'flex items-center px-4',
path?.startsWith(example.href) || (path === '/' && example.name === 'Dashboard') path?.startsWith(example.href) || (path === '/' && example.name === 'Mail')
? 'font-bold text-primary' ? 'font-bold text-primary'
: 'font-medium text-muted-foreground', : 'font-medium text-muted-foreground',
)" )"

View File

@ -11,7 +11,7 @@ import { buttonVariants } from '@/lib/registry/new-york/ui/button'
import { Separator } from '@/lib/registry/new-york/ui/separator' import { Separator } from '@/lib/registry/new-york/ui/separator'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import DashboardExample from '@/examples/dashboard/Example.vue' import MailExample from '@/examples/mail/Example.vue'
</script> </script>
<template> <template>
@ -55,17 +55,17 @@ import DashboardExample from '@/examples/dashboard/Example.vue'
<ExamplesNav /> <ExamplesNav />
<section class="space-y-8 overflow-hidden rounded-lg border-2 border-primary dark:border-muted md:hidden"> <section class="space-y-8 overflow-hidden rounded-lg border-2 border-primary dark:border-muted md:hidden">
<VPImage <VPImage
alt="Dashboard" alt="Mail"
width="1280" width="1280"
height="866" class="block" :image="{ height="866" class="block" :image="{
dark: '/examples/dashboard-dark.png', dark: '/examples/mail-dark.png',
light: '/examples/dashboard-light.png', light: '/examples/mail-light.png',
}" }"
/> />
</section> </section>
<section class="hidden md:block"> <section class="hidden md:block">
<div class="overflow-hidden rounded-[0.5rem] border bg-background shadow"> <div class="overflow-hidden rounded-[0.5rem] border bg-background shadow">
<DashboardExample /> <MailExample />
</div> </div>
</section> </section>
</template> </template>

View File

@ -23,7 +23,7 @@ interface DocsConfig {
export const docsConfig: DocsConfig = { export const docsConfig: DocsConfig = {
mainNav: [ mainNav: [
{ {
title: 'Documentation', title: 'Docs',
href: '/docs/introduction', href: '/docs/introduction',
}, },
{ {
@ -36,7 +36,7 @@ export const docsConfig: DocsConfig = {
}, },
{ {
title: 'Examples', title: 'Examples',
href: '/examples/dashboard', href: '/examples/mail',
}, },
{ {
title: 'GitHub', title: 'GitHub',
@ -386,6 +386,11 @@ interface Example {
code: string code: string
} }
export const examples: Example[] = [ export const examples: Example[] = [
{
name: 'Mail',
href: '/examples/mail',
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/mail',
},
{ {
name: 'Dashboard', name: 'Dashboard',
href: '/examples/dashboard', href: '/examples/dashboard',

View File

@ -120,7 +120,7 @@ watch(() => $route.path, (n) => {
> >
<div class="flex items-center"> <div class="flex items-center">
<SearchIcon class="w-4 h-4 mr-2 text-muted-foreground" /> <SearchIcon class="w-4 h-4 mr-2 text-muted-foreground" />
<span class="text-muted-foreground"> Search for anything... </span> <span class="text-muted-foreground"> Search documentation... </span>
</div> </div>
<div class="flex items-center gap-x-1"> <div class="flex items-center gap-x-1">
<Kbd> <span></span>K </Kbd> <Kbd> <span></span>K </Kbd>

View File

@ -0,0 +1,5 @@
<script setup>
import MailExample from "@/examples/mail/Example.vue"
</script>
<MailExample />

View File

@ -0,0 +1,30 @@
<script lang="ts" setup>
import Mail from './components/Mail.vue'
import { accounts, mails } from './data/mails'
</script>
<template>
<div class="md:hidden">
<image
src="/examples/mail-dark.png"
:width="1280"
:height="727"
alt="Mail"
class="hidden dark:block"
/>
<image
src="/examples/mail-light.png"
:width="1280"
:height="727"
alt="Mail"
class="block dark:hidden"
/>
</div>
<div class="hidden flex-col md:flex">
<Mail
:accounts="accounts"
:mails="mails"
:nav-collapsed-size="4"
/>
</div>
</template>

View File

@ -0,0 +1,49 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { Icon } from '@iconify/vue'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/lib/registry/new-york/ui/select'
import { cn } from '@/lib/utils'
interface AccountSwitcherProps {
isCollapsed: boolean
accounts: {
label: string
email: string
icon: string
}[]
}
const props = defineProps<AccountSwitcherProps>()
const selectedEmail = ref<string>(props.accounts[0].email)
const selectedEmailData = computed(() => props.accounts.find(item => item.email === selectedEmail.value))
</script>
<template>
<Select v-model="selectedEmail">
<SelectTrigger
aria-label="Select account"
:class="cn(
'flex items-center gap-2 [&>span]:line-clamp-1 [&>span]:flex [&>span]:w-full [&>span]:items-center [&>span]:gap-1 [&>span]:truncate [&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0',
{ 'flex h-9 w-9 shrink-0 items-center justify-center p-0 [&>span]:w-auto [&>svg]:hidden': isCollapsed },
)"
>
<SelectValue placeholder="Select an account">
<div class="flex items-center gap-3">
<Icon class="size-4" :icon="selectedEmailData!.icon" />
{{ selectedEmailData!.label }}
</div>
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem v-for="account of accounts" :key="account.email" :value="account.email">
<div class="flex items-center gap-3 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-foreground">
<Icon class="size-4" :icon="account.icon" />
<span v-if="!isCollapsed">
{{ account.email }}
</span>
</div>
</SelectItem>
</SelectContent>
</Select>
</template>

View File

@ -0,0 +1,221 @@
<script lang="ts" setup>
import {
Search,
} from 'lucide-vue-next'
import { computed, ref } from 'vue'
import { refDebounced } from '@vueuse/core'
import type { Mail } from '../data/mails'
import AccountSwitcher from './AccountSwitcher.vue'
import MailList from './MailList.vue'
import MailDisplay from './MailDisplay.vue'
import Nav, { type LinkProp } from './Nav.vue'
import { cn } from '@/lib/utils'
import { Separator } from '@/lib/registry/new-york/ui/separator'
import { Input } from '@/lib/registry/new-york/ui/input'
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '@/lib/registry/new-york/ui/tabs'
import { TooltipProvider } from '@/lib/registry/new-york/ui/tooltip'
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/lib/registry/new-york/ui/resizable'
interface MailProps {
accounts: {
label: string
email: string
icon: string
}[]
mails: Mail[]
defaultLayout?: number[]
defaultCollapsed?: boolean
navCollapsedSize: number
}
const props = withDefaults(defineProps<MailProps>(), {
defaultCollapsed: false,
defaultLayout: () => [265, 440, 655],
})
const isCollapsed = ref(props.defaultCollapsed)
const selectedMail = ref<string | undefined>(props.mails[0].id)
const searchValue = ref('')
const debouncedSearch = refDebounced(searchValue, 250)
const filteredMailList = computed(() => {
let output: Mail[] = []
const serachValue = debouncedSearch.value?.trim()
if (!serachValue) {
output = props.mails
}
else {
output = props.mails.filter((item) => {
return item.name.includes(debouncedSearch.value)
|| item.email.includes(debouncedSearch.value)
|| item.name.includes(debouncedSearch.value)
|| item.subject.includes(debouncedSearch.value)
|| item.text.includes(debouncedSearch.value)
})
}
return output
})
const unreadMailList = computed(() => filteredMailList.value.filter(item => !item.read))
const selectedMailData = computed(() => props.mails.find(item => item.id === selectedMail.value))
const links: LinkProp[] = [
{
title: 'Inbox',
label: '128',
icon: 'lucide:inbox',
variant: 'default',
},
{
title: 'Drafts',
label: '9',
icon: 'lucide:file',
variant: 'ghost',
},
{
title: 'Sent',
label: '',
icon: 'lucide:send',
variant: 'ghost',
},
{
title: 'Junk',
label: '23',
icon: 'lucide:archive',
variant: 'ghost',
},
{
title: 'Trash',
label: '',
icon: 'lucide:trash',
variant: 'ghost',
},
{
title: 'Archive',
label: '',
icon: 'lucide:archive',
variant: 'ghost',
},
]
const links2: LinkProp[] = [
{
title: 'Social',
label: '972',
icon: 'lucide:user-2',
variant: 'ghost',
},
{
title: 'Updates',
label: '342',
icon: 'lucide:alert-circle',
variant: 'ghost',
},
{
title: 'Forums',
label: '128',
icon: 'lucide:message-square',
variant: 'ghost',
},
{
title: 'Shopping',
label: '8',
icon: 'lucide:shopping-cart',
variant: 'ghost',
},
{
title: 'Promotions',
label: '21',
icon: 'lucide:archive',
variant: 'ghost',
},
]
function onCollapse() {
isCollapsed.value = true
}
function onExpand() {
isCollapsed.value = false
}
</script>
<template>
<TooltipProvider :delay-duration="0">
<ResizablePanelGroup
direction="horizontal"
class="h-full max-h-[800px] items-stretch"
>
<ResizablePanel
:default-size="defaultLayout[0]"
:collapsed-size="navCollapsedSize"
collapsible
:min-size="15"
:max-size="20"
:class="cn(isCollapsed && 'min-w-[50px] transition-all duration-300 ease-in-out')"
@expand="onExpand"
@collapse="onCollapse"
>
<div :class="cn('flex h-[52px] items-center justify-center', isCollapsed ? 'h-[52px]' : 'px-2')">
<AccountSwitcher :is-collapsed="isCollapsed" :accounts="accounts" />
</div>
<Separator />
<Nav
:is-collapsed="isCollapsed"
:links="links"
/>
<Separator />
<Nav
:is-collapsed="isCollapsed"
:links="links2"
/>
</ResizablePanel>
<ResizableHandle with-handle />
<ResizablePanel :default-size="defaultLayout[1]" :min-size="30">
<Tabs default-value="all">
<div class="flex items-center px-4 py-2">
<h1 class="text-xl font-bold">
Inbox
</h1>
<TabsList class="ml-auto">
<TabsTrigger value="all" class="text-zinc-600 dark:text-zinc-200">
All mail
</TabsTrigger>
<TabsTrigger value="unread" class="text-zinc-600 dark:text-zinc-200">
Unread
</TabsTrigger>
</TabsList>
</div>
<Separator />
<div class="bg-background/95 p-4 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<form>
<div class="relative">
<Search class="absolute left-2 top-2.5 size-4 text-muted-foreground" />
<Input v-model="searchValue" placeholder="Search" class="pl-8" />
</div>
</form>
</div>
<TabsContent value="all" class="m-0">
<MailList v-model:selected-mail="selectedMail" :items="filteredMailList" />
</TabsContent>
<TabsContent value="unread" class="m-0">
<MailList v-model:selected-mail="selectedMail" :items="unreadMailList" />
</TabsContent>
</Tabs>
</ResizablePanel>
<ResizableHandle with-handle />
<ResizablePanel :default-size="defaultLayout[2]">
<MailDisplay :mail="selectedMailData" />
</ResizablePanel>
</ResizablePanelGroup>
</TooltipProvider>
</template>

View File

@ -0,0 +1,236 @@
<script lang="ts" setup>
import { Archive, ArchiveX, Clock, Forward, MoreVertical, Reply, ReplyAll, Trash2 } from 'lucide-vue-next'
import { computed } from 'vue'
import addDays from 'date-fns/addDays'
import addHours from 'date-fns/addHours'
import format from 'date-fns/format'
import nextSaturday from 'date-fns/nextSaturday'
import type { Mail } from '../data/mails'
import { Calendar } from '@/lib/registry/new-york/ui/calendar'
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/lib/registry/new-york/ui/dropdown-menu'
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
import { Avatar, AvatarFallback } from '@/lib/registry/new-york/ui/avatar'
import { Button } from '@/lib/registry/new-york/ui/button'
import { Label } from '@/lib/registry/new-york/ui/label'
import { Separator } from '@/lib/registry/new-york/ui/separator'
import { Switch } from '@/lib/registry/new-york/ui/switch'
import { Textarea } from '@/lib/registry/new-york/ui/textarea'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/new-york/ui/tooltip'
interface MailDisplayProps {
mail: Mail | undefined
}
const props = defineProps<MailDisplayProps>()
const mailFallbackName = computed(() => {
return props.mail?.name
.split(' ')
.map(chunk => chunk[0])
.join('')
})
const today = new Date()
</script>
<template>
<div class="flex h-full flex-col">
<div class="flex items-center p-2">
<div class="flex items-center gap-2">
<Tooltip>
<TooltipTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<Archive class="size-4" />
<span class="sr-only">Archive</span>
</Button>
</TooltipTrigger>
<TooltipContent>Archive</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<ArchiveX class="size-4" />
<span class="sr-only">Move to junk</span>
</Button>
</TooltipTrigger>
<TooltipContent>Move to junk</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<Trash2 class="size-4" />
<span class="sr-only">Move to trash</span>
</Button>
</TooltipTrigger>
<TooltipContent>Move to trash</TooltipContent>
</Tooltip>
<Separator orientation="vertical" class="mx-1 h-6" />
<Tooltip>
<Popover>
<PopoverTrigger as-child>
<TooltipTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<Clock class="size-4" />
<span class="sr-only">Snooze</span>
</Button>
</TooltipTrigger>
</PopoverTrigger>
<PopoverContent class="flex w-[535px] p-0">
<div class="flex flex-col gap-2 border-r px-2 py-4">
<div class="px-4 text-sm font-medium">
Snooze until
</div>
<div class="grid min-w-[250px] gap-1">
<Button
variant="ghost"
class="justify-start font-normal"
>
Later today
<span class="ml-auto text-muted-foreground">
{{ format(addHours(today, 4), "E, h:m b") }}
</span>
</Button>
<Button
variant="ghost"
class="justify-start font-normal"
>
Tomorrow
<span class="ml-auto text-muted-foreground">
{{ format(addDays(today, 1), "E, h:m b") }}
</span>
</Button>
<Button
variant="ghost"
class="justify-start font-normal"
>
This weekend
<span class="ml-auto text-muted-foreground">
{{ format(nextSaturday(today), "E, h:m b") }}
</span>
</Button>
<Button
variant="ghost"
class="justify-start font-normal"
>
Next week
<span class="ml-auto text-muted-foreground">
{{ format(addDays(today, 7), "E, h:m b") }}
</span>
</Button>
</div>
</div>
<div class="p-2">
<Calendar />
</div>
</PopoverContent>
</Popover>
<TooltipContent>Snooze</TooltipContent>
</Tooltip>
</div>
<div class="ml-auto flex items-center gap-2">
<Tooltip>
<TooltipTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<Reply class="size-4" />
<span class="sr-only">Reply</span>
</Button>
</TooltipTrigger>
<TooltipContent>Reply</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<ReplyAll class="size-4" />
<span class="sr-only">Reply all</span>
</Button>
</TooltipTrigger>
<TooltipContent>Reply all</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<Forward class="size-4" />
<span class="sr-only">Forward</span>
</Button>
</TooltipTrigger>
<TooltipContent>Forward</TooltipContent>
</Tooltip>
</div>
<Separator orientation="vertical" class="mx-2 h-6" />
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="ghost" size="icon" :disabled="!mail">
<MoreVertical class="size-4" />
<span class="sr-only">More</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Mark as unread</DropdownMenuItem>
<DropdownMenuItem>Star thread</DropdownMenuItem>
<DropdownMenuItem>Add label</DropdownMenuItem>
<DropdownMenuItem>Mute thread</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<Separator />
<div v-if="mail" class="flex flex-1 flex-col">
<div class="flex items-start p-4">
<div class="flex items-start gap-4 text-sm">
<Avatar>
<AvatarFallback>
{{ mailFallbackName }}
</AvatarFallback>
</Avatar>
<div class="grid gap-1">
<div class="font-semibold">
{{ mail.name }}
</div>
<div class="line-clamp-1 text-xs">
{{ mail.subject }}
</div>
<div class="line-clamp-1 text-xs">
<span class="font-medium">Reply-To:</span> {{ mail.email }}
</div>
</div>
</div>
<div v-if="mail.date" class="ml-auto text-xs text-muted-foreground">
{{ format(new Date(mail.date), "PPpp") }}
</div>
</div>
<Separator />
<div class="flex-1 whitespace-pre-wrap p-4 text-sm">
{{ mail.text }}
</div>
<Separator class="mt-auto" />
<div class="p-4">
<form>
<div class="grid gap-4">
<Textarea
class="p-4"
:placeholder="`Reply ${mail.name}...`"
/>
<div class="flex items-center">
<Label
html-for="mute"
class="flex items-center gap-2 text-xs font-normal"
>
<Switch id="mute" aria-label="Mute thread" /> Mute this
thread
</Label>
<Button
type="button"
size="sm"
class="ml-auto"
>
Send
</Button>
</div>
</div>
</form>
</div>
</div>
<div v-else class="p-8 text-center text-muted-foreground">
No message selected
</div>
</div>
</template>

View File

@ -0,0 +1,93 @@
<script lang="ts" setup>
import { formatDistanceToNow } from 'date-fns'
import type { Mail } from '../data/mails'
import { ScrollArea } from '@/lib/registry/new-york/ui/scroll-area'
import { cn } from '@/lib/utils'
import { Badge } from '@/lib/registry/new-york/ui/badge'
interface MailListProps {
items: Mail[]
}
defineProps<MailListProps>()
const selectedMail = defineModel<string>('selectedMail', { required: false })
function getBadgeVariantFromLabel(label: string) {
if (['work'].includes(label.toLowerCase()))
return 'default'
if (['personal'].includes(label.toLowerCase()))
return 'outline'
return 'secondary'
}
</script>
<template>
<ScrollArea class="h-screen flex">
<div class="flex-1 flex flex-col gap-2 p-4 pt-0">
<TransitionGroup name="list" appear>
<button
v-for="item of items"
:key="item.id"
:class="cn(
'flex flex-col items-start gap-2 rounded-lg border p-3 text-left text-sm transition-all hover:bg-accent',
selectedMail === item.id && 'bg-muted',
)"
@click="selectedMail = item.id"
>
<div class="flex w-full flex-col gap-1">
<div class="flex items-center">
<div class="flex items-center gap-2">
<div class="font-semibold">
{{ item.name }}
</div>
<span v-if="!item.read" class="flex h-2 w-2 rounded-full bg-blue-600" />
</div>
<div
:class="cn(
'ml-auto text-xs',
selectedMail === item.id
? 'text-foreground'
: 'text-muted-foreground',
)"
>
{{ formatDistanceToNow(new Date(item.date), { addSuffix: true }) }}
</div>
</div>
<div class="text-xs font-medium">
{{ item.subject }}
</div>
</div>
<div class="line-clamp-2 text-xs text-muted-foreground">
{{ item.text.substring(0, 300) }}
</div>
<div class="flex items-center gap-2">
<Badge v-for="label of item.labels" :key="label" :variant="getBadgeVariantFromLabel(label)">
{{ label }}
</Badge>
</div>
</button>
</TransitionGroup>
</div>
</ScrollArea>
</template>
<style scoped>
.list-move,
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateY(15px);
}
.list-leave-active {
position: absolute;
}
</style>

View File

@ -0,0 +1,83 @@
<script lang="ts" setup>
import { Icon } from '@iconify/vue'
import { cn } from '@/lib/utils'
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/lib/registry/new-york/ui/tooltip'
export interface LinkProp {
title: string
label?: string
icon: string
variant: 'default' | 'ghost'
}
interface NavProps {
isCollapsed: boolean
links: LinkProp[]
}
defineProps<NavProps>()
</script>
<template>
<div
:data-collapsed="isCollapsed"
class="group flex flex-col gap-4 py-2 data-[collapsed=true]:py-2"
>
<nav class="grid gap-1 px-2 group-[[data-collapsed=true]]:justify-center group-[[data-collapsed=true]]:px-2">
<template v-for="(link, index) of links">
<Tooltip v-if="isCollapsed" :key="`1-${index}`" :delay-duration="0">
<TooltipTrigger as-child>
<a
href="#"
:class="cn(
buttonVariants({ variant: link.variant, size: 'icon' }),
'h-9 w-9',
link.variant === 'default'
&& 'dark:bg-muted dark:text-muted-foreground dark:hover:bg-muted dark:hover:text-white',
)"
>
<Icon :icon="link.icon" class="size-4" />
<span class="sr-only">{{ link.title }}</span>
</a>
</TooltipTrigger>
<TooltipContent side="right" class="flex items-center gap-4">
{{ link.title }}
<span v-if="link.label" class="ml-auto text-muted-foreground">
{{ link.label }}
</span>
</TooltipContent>
</Tooltip>
<a
v-else
:key="`2-${index}`"
href="#"
:class="cn(
buttonVariants({ variant: link.variant, size: 'sm' }),
link.variant === 'default'
&& 'dark:bg-muted dark:text-white dark:hover:bg-muted dark:hover:text-white',
'justify-start',
)"
>
<Icon :icon="link.icon" class="mr-2 size-4" />
{{ link.title }}
<span
v-if="link.label"
:class="cn(
'ml-auto',
link.variant === 'default'
&& 'text-background dark:text-white',
)"
>
{{ link.label }}
</span>
</a>
</template>
</nav>
</div>
</template>

View File

@ -0,0 +1,279 @@
export const mails = [
{
id: '6c84fb90-12c4-11e1-840d-7b25c5ee775a',
name: 'William Smith',
email: 'williamsmith@example.com',
subject: 'Meeting Tomorrow',
text: 'Hi, let\'s have a meeting tomorrow to discuss the project. I\'ve been reviewing the project details and have some ideas I\'d like to share. It\'s crucial that we align on our next steps to ensure the project\'s success.\n\nPlease come prepared with any questions or insights you may have. Looking forward to our meeting!\n\nBest regards, William',
date: '2023-10-22T09:00:00',
read: true,
labels: ['meeting', 'work', 'important'],
},
{
id: '110e8400-e29b-11d4-a716-446655440000',
name: 'Alice Smith',
email: 'alicesmith@example.com',
subject: 'Re: Project Update',
text: 'Thank you for the project update. It looks great! I\'ve gone through the report, and the progress is impressive. The team has done a fantastic job, and I appreciate the hard work everyone has put in.\n\nI have a few minor suggestions that I\'ll include in the attached document.\n\nLet\'s discuss these during our next meeting. Keep up the excellent work!\n\nBest regards, Alice',
date: '2023-10-22T10:30:00',
read: true,
labels: ['work', 'important'],
},
{
id: '3e7c3f6d-bdf5-46ae-8d90-171300f27ae2',
name: 'Bob Johnson',
email: 'bobjohnson@example.com',
subject: 'Weekend Plans',
text: 'Any plans for the weekend? I was thinking of going hiking in the nearby mountains. It\'s been a while since we had some outdoor fun.\n\nIf you\'re interested, let me know, and we can plan the details. It\'ll be a great way to unwind and enjoy nature.\n\nLooking forward to your response!\n\nBest, Bob',
date: '2023-04-10T11:45:00',
read: true,
labels: ['personal'],
},
{
id: '61c35085-72d7-42b4-8d62-738f700d4b92',
name: 'Emily Davis',
email: 'emilydavis@example.com',
subject: 'Re: Question about Budget',
text: 'I have a question about the budget for the upcoming project. It seems like there\'s a discrepancy in the allocation of resources.\n\nI\'ve reviewed the budget report and identified a few areas where we might be able to optimize our spending without compromising the project\'s quality.\n\nI\'ve attached a detailed analysis for your reference. Let\'s discuss this further in our next meeting.\n\nThanks, Emily',
date: '2023-03-25T13:15:00',
read: false,
labels: ['work', 'budget'],
},
{
id: '8f7b5db9-d935-4e42-8e05-1f1d0a3dfb97',
name: 'Michael Wilson',
email: 'michaelwilson@example.com',
subject: 'Important Announcement',
text: 'I have an important announcement to make during our team meeting. It pertains to a strategic shift in our approach to the upcoming product launch. We\'ve received valuable feedback from our beta testers, and I believe it\'s time to make some adjustments to better meet our customers\' needs.\n\nThis change is crucial to our success, and I look forward to discussing it with the team. Please be prepared to share your insights during the meeting.\n\nRegards, Michael',
date: '2023-03-10T15:00:00',
read: false,
labels: ['meeting', 'work', 'important'],
},
{
id: '1f0f2c02-e299-40de-9b1d-86ef9e42126b',
name: 'Sarah Brown',
email: 'sarahbrown@example.com',
subject: 'Re: Feedback on Proposal',
text: 'Thank you for your feedback on the proposal. It looks great! I\'m pleased to hear that you found it promising. The team worked diligently to address all the key points you raised, and I believe we now have a strong foundation for the project.\n\nI\'ve attached the revised proposal for your review.\n\nPlease let me know if you have any further comments or suggestions. Looking forward to your response.\n\nBest regards, Sarah',
date: '2023-02-15T16:30:00',
read: true,
labels: ['work'],
},
{
id: '17c0a96d-4415-42b1-8b4f-764efab57f66',
name: 'David Lee',
email: 'davidlee@example.com',
subject: 'New Project Idea',
text: 'I have an exciting new project idea to discuss with you. It involves expanding our services to target a niche market that has shown considerable growth in recent months.\n\nI\'ve prepared a detailed proposal outlining the potential benefits and the strategy for execution.\n\nThis project has the potential to significantly impact our business positively. Let\'s set up a meeting to dive into the details and determine if it aligns with our current goals.\n\nBest regards, David',
date: '2023-01-28T17:45:00',
read: false,
labels: ['meeting', 'work', 'important'],
},
{
id: '2f0130cb-39fc-44c4-bb3c-0a4337edaaab',
name: 'Olivia Wilson',
email: 'oliviawilson@example.com',
subject: 'Vacation Plans',
text: 'Let\'s plan our vacation for next month. What do you think? I\'ve been thinking of visiting a tropical paradise, and I\'ve put together some destination options.\n\nI believe it\'s time for us to unwind and recharge. Please take a look at the options and let me know your preferences.\n\nWe can start making arrangements to ensure a smooth and enjoyable trip.\n\nExcited to hear your thoughts! Olivia',
date: '2022-12-20T18:30:00',
read: true,
labels: ['personal'],
},
{
id: 'de305d54-75b4-431b-adb2-eb6b9e546014',
name: 'James Martin',
email: 'jamesmartin@example.com',
subject: 'Re: Conference Registration',
text: 'I\'ve completed the registration for the conference next month. The event promises to be a great networking opportunity, and I\'m looking forward to attending the various sessions and connecting with industry experts.\n\nI\'ve also attached the conference schedule for your reference.\n\nIf there are any specific topics or sessions you\'d like me to explore, please let me know. It\'s an exciting event, and I\'ll make the most of it.\n\nBest regards, James',
date: '2022-11-30T19:15:00',
read: true,
labels: ['work', 'conference'],
},
{
id: '7dd90c63-00f6-40f3-bd87-5060a24e8ee7',
name: 'Sophia White',
email: 'sophiawhite@example.com',
subject: 'Team Dinner',
text: 'Let\'s have a team dinner next week to celebrate our success. We\'ve achieved some significant milestones, and it\'s time to acknowledge our hard work and dedication.\n\nI\'ve made reservations at a lovely restaurant, and I\'m sure it\'ll be an enjoyable evening.\n\nPlease confirm your availability and any dietary preferences. Looking forward to a fun and memorable dinner with the team!\n\nBest, Sophia',
date: '2022-11-05T20:30:00',
read: false,
labels: ['meeting', 'work'],
},
{
id: '99a88f78-3eb4-4d87-87b7-7b15a49a0a05',
name: 'Daniel Johnson',
email: 'danieljohnson@example.com',
subject: 'Feedback Request',
text: 'I\'d like your feedback on the latest project deliverables. We\'ve made significant progress, and I value your input to ensure we\'re on the right track.\n\nI\'ve attached the deliverables for your review, and I\'m particularly interested in any areas where you think we can further enhance the quality or efficiency.\n\nYour feedback is invaluable, and I appreciate your time and expertise. Let\'s work together to make this project a success.\n\nRegards, Daniel',
date: '2022-10-22T09:30:00',
read: false,
labels: ['work'],
},
{
id: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'Ava Taylor',
email: 'avataylor@example.com',
subject: 'Re: Meeting Agenda',
text: 'Here\'s the agenda for our meeting next week. I\'ve included all the topics we need to cover, as well as time allocations for each.\n\nIf you have any additional items to discuss or any specific points to address, please let me know, and we can integrate them into the agenda.\n\nIt\'s essential that our meeting is productive and addresses all relevant matters.\n\nLooking forward to our meeting! Ava',
date: '2022-10-10T10:45:00',
read: true,
labels: ['meeting', 'work'],
},
{
id: 'c1a0ecb4-2540-49c5-86f8-21e5ce79e4e6',
name: 'William Anderson',
email: 'williamanderson@example.com',
subject: 'Product Launch Update',
text: 'The product launch is on track. I\'ll provide an update during our call. We\'ve made substantial progress in the development and marketing of our new product.\n\nI\'m excited to share the latest updates with you during our upcoming call. It\'s crucial that we coordinate our efforts to ensure a successful launch. Please come prepared with any questions or insights you may have.\n\nLet\'s make this product launch a resounding success!\n\nBest regards, William',
date: '2022-09-20T12:00:00',
read: false,
labels: ['meeting', 'work', 'important'],
},
{
id: 'ba54eefd-4097-4949-99f2-2a9ae4d1a836',
name: 'Mia Harris',
email: 'miaharris@example.com',
subject: 'Re: Travel Itinerary',
text: 'I\'ve received the travel itinerary. It looks great! Thank you for your prompt assistance in arranging the details. I\'ve reviewed the schedule and the accommodations, and everything seems to be in order. I\'m looking forward to the trip, and I\'m confident it\'ll be a smooth and enjoyable experience.\n\nIf there are any specific activities or attractions you recommend at our destination, please feel free to share your suggestions.\n\nExcited for the trip! Mia',
date: '2022-09-10T13:15:00',
read: true,
labels: ['personal', 'travel'],
},
{
id: 'df09b6ed-28bd-4e0c-85a9-9320ec5179aa',
name: 'Ethan Clark',
email: 'ethanclark@example.com',
subject: 'Team Building Event',
text: 'Let\'s plan a team-building event for our department. Team cohesion and morale are vital to our success, and I believe a well-organized team-building event can be incredibly beneficial. I\'ve done some research and have a few ideas for fun and engaging activities.\n\nPlease let me know your thoughts and availability. We want this event to be both enjoyable and productive.\n\nTogether, we\'ll strengthen our team and boost our performance.\n\nRegards, Ethan',
date: '2022-08-25T15:30:00',
read: false,
labels: ['meeting', 'work'],
},
{
id: 'd67c1842-7f8b-4b4b-9be1-1b3b1ab4611d',
name: 'Chloe Hall',
email: 'chloehall@example.com',
subject: 'Re: Budget Approval',
text: 'The budget has been approved. We can proceed with the project. I\'m delighted to inform you that our budget proposal has received the green light from the finance department. This is a significant milestone, and it means we can move forward with the project as planned.\n\nI\'ve attached the finalized budget for your reference. Let\'s ensure that we stay on track and deliver the project on time and within budget.\n\nIt\'s an exciting time for us! Chloe',
date: '2022-08-10T16:45:00',
read: true,
labels: ['work', 'budget'],
},
{
id: '6c9a7f94-8329-4d70-95d3-51f68c186ae1',
name: 'Samuel Turner',
email: 'samuelturner@example.com',
subject: 'Weekend Hike',
text: 'Who\'s up for a weekend hike in the mountains? I\'ve been craving some outdoor adventure, and a hike in the mountains sounds like the perfect escape. If you\'re up for the challenge, we can explore some scenic trails and enjoy the beauty of nature.\n\nI\'ve done some research and have a few routes in mind.\n\nLet me know if you\'re interested, and we can plan the details.\n\nIt\'s sure to be a memorable experience! Samuel',
date: '2022-07-28T17:30:00',
read: false,
labels: ['personal'],
},
]
export type Mail = (typeof mails)[number]
export const accounts = [
{
label: 'Alicia Koch',
email: 'alicia@example.com',
icon: 'ion:logo-vercel',
},
{
label: 'Alicia Koch',
email: 'alicia@gmail.com',
icon: 'mdi:google',
},
{
label: 'Alicia Koch',
email: 'alicia@me.com',
icon: 'bx:bxl-gmail',
},
]
export type Account = (typeof accounts)[number]
export const contacts = [
{
name: 'Emma Johnson',
email: 'emma.johnson@example.com',
},
{
name: 'Liam Wilson',
email: 'liam.wilson@example.com',
},
{
name: 'Olivia Davis',
email: 'olivia.davis@example.com',
},
{
name: 'Noah Martinez',
email: 'noah.martinez@example.com',
},
{
name: 'Ava Taylor',
email: 'ava.taylor@example.com',
},
{
name: 'Lucas Brown',
email: 'lucas.brown@example.com',
},
{
name: 'Sophia Smith',
email: 'sophia.smith@example.com',
},
{
name: 'Ethan Wilson',
email: 'ethan.wilson@example.com',
},
{
name: 'Isabella Jackson',
email: 'isabella.jackson@example.com',
},
{
name: 'Mia Clark',
email: 'mia.clark@example.com',
},
{
name: 'Mason Lee',
email: 'mason.lee@example.com',
},
{
name: 'Layla Harris',
email: 'layla.harris@example.com',
},
{
name: 'William Anderson',
email: 'william.anderson@example.com',
},
{
name: 'Ella White',
email: 'ella.white@example.com',
},
{
name: 'James Thomas',
email: 'james.thomas@example.com',
},
{
name: 'Harper Lewis',
email: 'harper.lewis@example.com',
},
{
name: 'Benjamin Moore',
email: 'benjamin.moore@example.com',
},
{
name: 'Aria Hall',
email: 'aria.hall@example.com',
},
{
name: 'Henry Turner',
email: 'henry.turner@example.com',
},
{
name: 'Scarlett Adams',
email: 'scarlett.adams@example.com',
},
]
export type Contact = (typeof contacts)[number]

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB