├── .editorconfig ├── .env.example ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .npmrc ├── README.md ├── app ├── app.config.ts ├── app.vue ├── assets │ └── css │ │ └── main.css ├── components │ ├── NotificationsSlideover.vue │ ├── TeamsMenu.vue │ ├── UserMenu.vue │ ├── customers │ │ ├── AddModal.vue │ │ └── DeleteModal.vue │ ├── home │ │ ├── HomeChart.client.vue │ │ ├── HomeChart.server.vue │ │ ├── HomeDateRangePicker.vue │ │ ├── HomePeriodSelect.vue │ │ ├── HomeSales.vue │ │ └── HomeStats.vue │ ├── inbox │ │ ├── InboxList.vue │ │ └── InboxMail.vue │ └── settings │ │ └── MembersList.vue ├── composables │ └── useDashboard.ts ├── error.vue ├── layouts │ └── default.vue ├── pages │ ├── customers.vue │ ├── inbox.vue │ ├── index.vue │ ├── settings.vue │ └── settings │ │ ├── index.vue │ │ ├── members.vue │ │ ├── notifications.vue │ │ └── security.vue ├── types │ └── index.d.ts └── utils │ └── index.ts ├── eslint.config.mjs ├── nuxt.config.ts ├── package.json ├── pnpm-lock.yaml ├── public └── favicon.ico ├── renovate.json ├── server └── api │ ├── customers.ts │ ├── mails.ts │ ├── members.ts │ └── notifications.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Production license for @nuxt/ui-pro, get one at https://ui.nuxt.com/pro/purchase 2 | NUXT_UI_PRO_LICENSE= 3 | # Public URL, used for OG Image when running nuxt generate 4 | NUXT_PUBLIC_SITE_URL= 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: push 4 | 5 | jobs: 6 | ci: 7 | runs-on: ${{ matrix.os }} 8 | 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest] 12 | node: [22] 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | 18 | - name: Install pnpm 19 | uses: pnpm/action-setup@v4 20 | 21 | - name: Install node 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: ${{ matrix.node }} 25 | cache: pnpm 26 | 27 | - name: Install dependencies 28 | run: pnpm install 29 | 30 | - name: Lint 31 | run: pnpm run lint 32 | 33 | - name: Typecheck 34 | run: pnpm run typecheck 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | 26 | # VSC 27 | .history 28 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nuxt Dashboard Template 2 | 3 | [![Nuxt UI Pro](https://img.shields.io/badge/Made%20with-Nuxt%20UI%20Pro-00DC82?logo=nuxt&labelColor=020420)](https://ui.nuxt.com/pro) 4 | [![Deploy to NuxtHub](https://img.shields.io/badge/Deploy%20to-NuxtHub-00DC82?logo=nuxt&labelColor=020420)](https://hub.nuxt.com/new?repo=nuxt-ui-pro/dashboard) 5 | 6 | Get started with the Nuxt dashboard template with multiple pages, collapsible sidebar, keyboard shortcuts, light & dark more, command palette and more, powered by [Nuxt UI Pro](https://ui.nuxt.com/pro). 7 | 8 | - [Live demo](https://dashboard-template.nuxt.dev/) 9 | - [Documentation](https://ui.nuxt.com/getting-started/installation/pro/nuxt) 10 | 11 | 12 | 13 | 14 | 15 | Nuxt Dashboard Template 16 | 17 | 18 | 19 | ## Vue Dashboard Template 20 | 21 | The dashboard template for Vue is on https://github.com/nuxt-ui-pro/dashboard-vue. 22 | 23 | ## Quick Start 24 | 25 | ```bash [Terminal] 26 | npx nuxi@latest init -t github:nuxt-ui-pro/dashboard 27 | ``` 28 | 29 | ## Setup 30 | 31 | Make sure to install the dependencies: 32 | 33 | ```bash 34 | pnpm install 35 | ``` 36 | 37 | ## Development Server 38 | 39 | Start the development server on `http://localhost:3000`: 40 | 41 | ```bash 42 | pnpm dev 43 | ``` 44 | 45 | ## Production 46 | 47 | Build the application for production: 48 | 49 | ```bash 50 | pnpm build 51 | ``` 52 | 53 | Locally preview production build: 54 | 55 | ```bash 56 | pnpm preview 57 | ``` 58 | 59 | Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. 60 | 61 | ## Renovate integration 62 | 63 | Install [Renovate GitHub app](https://github.com/apps/renovate/installations/select_target) on your repository and you are good to go. 64 | -------------------------------------------------------------------------------- /app/app.config.ts: -------------------------------------------------------------------------------- 1 | export default defineAppConfig({ 2 | ui: { 3 | colors: { 4 | primary: 'green', 5 | neutral: 'zinc' 6 | } 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /app/app.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 43 | -------------------------------------------------------------------------------- /app/assets/css/main.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss" theme(static); 2 | @import "@nuxt/ui-pro"; 3 | 4 | @theme static { 5 | --font-sans: 'Public Sans', sans-serif; 6 | 7 | --color-green-50: #EFFDF5; 8 | --color-green-100: #D9FBE8; 9 | --color-green-200: #B3F5D1; 10 | --color-green-300: #75EDAE; 11 | --color-green-400: #00DC82; 12 | --color-green-500: #00C16A; 13 | --color-green-600: #00A155; 14 | --color-green-700: #007F45; 15 | --color-green-800: #016538; 16 | --color-green-900: #0A5331; 17 | --color-green-950: #052E16; 18 | } 19 | -------------------------------------------------------------------------------- /app/components/NotificationsSlideover.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 53 | -------------------------------------------------------------------------------- /app/components/TeamsMenu.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 69 | -------------------------------------------------------------------------------- /app/components/UserMenu.vue: -------------------------------------------------------------------------------- 1 | 151 | 152 | 185 | -------------------------------------------------------------------------------- /app/components/customers/AddModal.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 60 | -------------------------------------------------------------------------------- /app/components/customers/DeleteModal.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 43 | -------------------------------------------------------------------------------- /app/components/home/HomeChart.client.vue: -------------------------------------------------------------------------------- 1 | 62 | 63 | 109 | 110 | 124 | -------------------------------------------------------------------------------- /app/components/home/HomeChart.server.vue: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /app/components/home/HomeDateRangePicker.vue: -------------------------------------------------------------------------------- 1 | 79 | 80 | 133 | -------------------------------------------------------------------------------- /app/components/home/HomePeriodSelect.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 50 | -------------------------------------------------------------------------------- /app/components/home/HomeSales.vue: -------------------------------------------------------------------------------- 1 | 98 | 99 | 113 | -------------------------------------------------------------------------------- /app/components/home/HomeStats.vue: -------------------------------------------------------------------------------- 1 | 65 | 66 | 99 | -------------------------------------------------------------------------------- /app/components/inbox/InboxList.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 79 | -------------------------------------------------------------------------------- /app/components/inbox/InboxMail.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 166 | -------------------------------------------------------------------------------- /app/components/settings/MembersList.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 61 | -------------------------------------------------------------------------------- /app/composables/useDashboard.ts: -------------------------------------------------------------------------------- 1 | import { createSharedComposable } from '@vueuse/core' 2 | 3 | const _useDashboard = () => { 4 | const route = useRoute() 5 | const router = useRouter() 6 | const isNotificationsSlideoverOpen = ref(false) 7 | 8 | defineShortcuts({ 9 | 'g-h': () => router.push('/'), 10 | 'g-i': () => router.push('/inbox'), 11 | 'g-c': () => router.push('/customers'), 12 | 'g-s': () => router.push('/settings'), 13 | 'n': () => isNotificationsSlideoverOpen.value = !isNotificationsSlideoverOpen.value 14 | }) 15 | 16 | watch(() => route.fullPath, () => { 17 | isNotificationsSlideoverOpen.value = false 18 | }) 19 | 20 | return { 21 | isNotificationsSlideoverOpen 22 | } 23 | } 24 | 25 | export const useDashboard = createSharedComposable(_useDashboard) 26 | -------------------------------------------------------------------------------- /app/error.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 116 | 117 | 163 | -------------------------------------------------------------------------------- /app/pages/customers.vue: -------------------------------------------------------------------------------- 1 | 198 | 199 | 321 | -------------------------------------------------------------------------------- /app/pages/inbox.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 91 | -------------------------------------------------------------------------------- /app/pages/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 70 | -------------------------------------------------------------------------------- /app/pages/settings.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 56 | -------------------------------------------------------------------------------- /app/pages/settings/index.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 159 | -------------------------------------------------------------------------------- /app/pages/settings/members.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 46 | -------------------------------------------------------------------------------- /app/pages/settings/notifications.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 72 | -------------------------------------------------------------------------------- /app/pages/settings/security.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 70 | -------------------------------------------------------------------------------- /app/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { AvatarProps } from '@nuxt/ui' 2 | 3 | export type UserStatus = 'subscribed' | 'unsubscribed' | 'bounced' 4 | export type SaleStatus = 'paid' | 'failed' | 'refunded' 5 | 6 | export interface User { 7 | id: number 8 | name: string 9 | email: string 10 | avatar?: AvatarProps 11 | status: UserStatus 12 | location: string 13 | } 14 | 15 | export interface Mail { 16 | id: number 17 | unread?: boolean 18 | from: User 19 | subject: string 20 | body: string 21 | date: string 22 | } 23 | 24 | export interface Member { 25 | name: string 26 | username: string 27 | role: 'member' | 'owner' 28 | avatar: Avatar 29 | } 30 | 31 | export interface Stat { 32 | title: string 33 | icon: string 34 | value: number | string 35 | variation: number 36 | formatter?: (value: number) => string 37 | } 38 | 39 | export interface Sale { 40 | id: string 41 | date: string 42 | status: SaleStatus 43 | email: string 44 | amount: number 45 | } 46 | 47 | export interface Notification { 48 | id: number 49 | unread?: boolean 50 | sender: User 51 | body: string 52 | date: string 53 | } 54 | 55 | export type Period = 'daily' | 'weekly' | 'monthly' 56 | 57 | export interface Range { 58 | start: Date 59 | end: Date 60 | } 61 | -------------------------------------------------------------------------------- /app/utils/index.ts: -------------------------------------------------------------------------------- 1 | export function randomInt(min: number, max: number): number { 2 | return Math.floor(Math.random() * (max - min + 1)) + min 3 | } 4 | 5 | export function randomFrom(array: T[]): T { 6 | return array[Math.floor(Math.random() * array.length)]! 7 | } 8 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import withNuxt from './.nuxt/eslint.config.mjs' 3 | 4 | export default withNuxt({ 5 | rules: { 6 | 'vue/no-multiple-template-root': 'off', 7 | 'vue/max-attributes-per-line': ['error', { singleline: 3 }] 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | modules: [ 4 | '@nuxt/eslint', 5 | '@nuxt/ui-pro', 6 | '@vueuse/nuxt' 7 | ], 8 | 9 | devtools: { 10 | enabled: true 11 | }, 12 | 13 | css: ['~/assets/css/main.css'], 14 | 15 | routeRules: { 16 | '/api/**': { 17 | cors: true 18 | } 19 | }, 20 | 21 | future: { 22 | compatibilityVersion: 4 23 | }, 24 | 25 | compatibilityDate: '2024-07-11', 26 | 27 | eslint: { 28 | config: { 29 | stylistic: { 30 | commaDangle: 'never', 31 | braceStyle: '1tbs' 32 | } 33 | } 34 | } 35 | }) 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-ui-pro-template-dashboard", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare", 11 | "lint": "eslint .", 12 | "typecheck": "nuxt typecheck" 13 | }, 14 | "dependencies": { 15 | "@iconify-json/lucide": "^1.2.44", 16 | "@iconify-json/simple-icons": "^1.2.35", 17 | "@nuxt/ui-pro": "^3.1.3", 18 | "@unovis/ts": "^1.5.2", 19 | "@unovis/vue": "^1.5.2", 20 | "@vueuse/nuxt": "^13.2.0", 21 | "date-fns": "^4.1.0", 22 | "nuxt": "^3.17.5", 23 | "zod": "^3.25.28" 24 | }, 25 | "devDependencies": { 26 | "@nuxt/eslint": "^1.4.1", 27 | "eslint": "^9.27.0", 28 | "typescript": "^5.8.3", 29 | "vue-tsc": "^2.2.10" 30 | }, 31 | "resolutions": { 32 | "unimport": "4.1.1" 33 | }, 34 | "pnpm": { 35 | "ignoredBuiltDependencies": [ 36 | "@parcel/watcher", 37 | "esbuild", 38 | "maplibre-gl", 39 | "vue-demi" 40 | ] 41 | }, 42 | "packageManager": "pnpm@10.11.0" 43 | } 44 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxt-ui-pro/dashboard/bebfd347268fb63787884cbc4b35aaf0b00763fa/public/favicon.ico -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "github>nuxt/renovate-config-nuxt" 4 | ], 5 | "lockFileMaintenance": { 6 | "enabled": true 7 | }, 8 | "baseBranches": ["v1", "main"], 9 | "packageRules": [{ 10 | "matchDepTypes": ["resolutions"], 11 | "enabled": false 12 | }], 13 | "postUpdateOptions": ["pnpmDedupe"] 14 | } 15 | -------------------------------------------------------------------------------- /server/api/customers.ts: -------------------------------------------------------------------------------- 1 | import type { User } from '~/types' 2 | 3 | const customers: User[] = [{ 4 | id: 1, 5 | name: 'Alex Smith', 6 | email: 'alex.smith@example.com', 7 | avatar: { 8 | src: 'https://i.pravatar.cc/128?u=1' 9 | }, 10 | status: 'subscribed', 11 | location: 'New York, USA' 12 | }, { 13 | id: 2, 14 | name: 'Jordan Brown', 15 | email: 'jordan.brown@example.com', 16 | avatar: { 17 | src: 'https://i.pravatar.cc/128?u=2' 18 | }, 19 | status: 'unsubscribed', 20 | location: 'London, UK' 21 | }, { 22 | id: 3, 23 | name: 'Taylor Green', 24 | email: 'taylor.green@example.com', 25 | avatar: { 26 | src: 'https://i.pravatar.cc/128?u=3' 27 | }, 28 | status: 'bounced', 29 | location: 'Paris, France' 30 | }, { 31 | id: 4, 32 | name: 'Morgan White', 33 | email: 'morgan.white@example.com', 34 | avatar: { 35 | src: 'https://i.pravatar.cc/128?u=4' 36 | }, 37 | status: 'subscribed', 38 | location: 'Berlin, Germany' 39 | }, { 40 | id: 5, 41 | name: 'Casey Gray', 42 | email: 'casey.gray@example.com', 43 | avatar: { 44 | src: 'https://i.pravatar.cc/128?u=5' 45 | }, 46 | status: 'subscribed', 47 | location: 'Tokyo, Japan' 48 | }, { 49 | id: 6, 50 | name: 'Jamie Johnson', 51 | email: 'jamie.johnson@example.com', 52 | avatar: { 53 | src: 'https://i.pravatar.cc/128?u=6' 54 | }, 55 | status: 'subscribed', 56 | location: 'Sydney, Australia' 57 | }, { 58 | id: 7, 59 | name: 'Riley Davis', 60 | email: 'riley.davis@example.com', 61 | avatar: { 62 | src: 'https://i.pravatar.cc/128?u=7' 63 | }, 64 | status: 'subscribed', 65 | location: 'New York, USA' 66 | }, { 67 | id: 8, 68 | name: 'Kelly Wilson', 69 | email: 'kelly.wilson@example.com', 70 | avatar: { 71 | src: 'https://i.pravatar.cc/128?u=8' 72 | }, 73 | status: 'subscribed', 74 | location: 'London, UK' 75 | }, { 76 | id: 9, 77 | name: 'Drew Moore', 78 | email: 'drew.moore@example.com', 79 | avatar: { 80 | src: 'https://i.pravatar.cc/128?u=9' 81 | }, 82 | status: 'bounced', 83 | location: 'Paris, France' 84 | }, { 85 | id: 10, 86 | name: 'Jordan Taylor', 87 | email: 'jordan.taylor@example.com', 88 | avatar: { 89 | src: 'https://i.pravatar.cc/128?u=10' 90 | }, 91 | status: 'subscribed', 92 | location: 'Berlin, Germany' 93 | }, { 94 | id: 11, 95 | name: 'Morgan Anderson', 96 | email: 'morgan.anderson@example.com', 97 | avatar: { 98 | src: 'https://i.pravatar.cc/128?u=11' 99 | }, 100 | status: 'subscribed', 101 | location: 'Tokyo, Japan' 102 | }, { 103 | id: 12, 104 | name: 'Casey Thomas', 105 | email: 'casey.thomas@example.com', 106 | avatar: { 107 | src: 'https://i.pravatar.cc/128?u=12' 108 | }, 109 | status: 'unsubscribed', 110 | location: 'Sydney, Australia' 111 | }, { 112 | id: 13, 113 | name: 'Jamie Jackson', 114 | email: 'jamie.jackson@example.com', 115 | avatar: { 116 | src: 'https://i.pravatar.cc/128?u=13' 117 | }, 118 | status: 'unsubscribed', 119 | location: 'New York, USA' 120 | }, { 121 | id: 14, 122 | name: 'Riley White', 123 | email: 'riley.white@example.com', 124 | avatar: { 125 | src: 'https://i.pravatar.cc/128?u=14' 126 | }, 127 | status: 'unsubscribed', 128 | location: 'London, UK' 129 | }, { 130 | id: 15, 131 | name: 'Kelly Harris', 132 | email: 'kelly.harris@example.com', 133 | avatar: { 134 | src: 'https://i.pravatar.cc/128?u=15' 135 | }, 136 | status: 'subscribed', 137 | location: 'Paris, France' 138 | }, { 139 | id: 16, 140 | name: 'Drew Martin', 141 | email: 'drew.martin@example.com', 142 | avatar: { 143 | src: 'https://i.pravatar.cc/128?u=16' 144 | }, 145 | status: 'subscribed', 146 | location: 'Berlin, Germany' 147 | }, { 148 | id: 17, 149 | name: 'Alex Thompson', 150 | email: 'alex.thompson@example.com', 151 | avatar: { 152 | src: 'https://i.pravatar.cc/128?u=17' 153 | }, 154 | status: 'unsubscribed', 155 | location: 'Tokyo, Japan' 156 | }, { 157 | id: 18, 158 | name: 'Jordan Garcia', 159 | email: 'jordan.garcia@example.com', 160 | avatar: { 161 | src: 'https://i.pravatar.cc/128?u=18' 162 | }, 163 | status: 'subscribed', 164 | location: 'Sydney, Australia' 165 | }, { 166 | id: 19, 167 | name: 'Taylor Rodriguez', 168 | email: 'taylor.rodriguez@example.com', 169 | avatar: { 170 | src: 'https://i.pravatar.cc/128?u=19' 171 | }, 172 | status: 'bounced', 173 | location: 'New York, USA' 174 | }, { 175 | id: 20, 176 | name: 'Morgan Lopez', 177 | email: 'morgan.lopez@example.com', 178 | avatar: { 179 | src: 'https://i.pravatar.cc/128?u=20' 180 | }, 181 | status: 'subscribed', 182 | location: 'London, UK' 183 | }] 184 | 185 | export default eventHandler(async () => { 186 | return customers 187 | }) 188 | -------------------------------------------------------------------------------- /server/api/mails.ts: -------------------------------------------------------------------------------- 1 | import { sub } from 'date-fns' 2 | 3 | const mails = [{ 4 | id: 1, 5 | from: { 6 | name: 'Alex Smith', 7 | email: 'alex.smith@example.com', 8 | avatar: { 9 | src: 'https://i.pravatar.cc/128?u=1' 10 | } 11 | }, 12 | subject: 'Meeting Schedule: Q1 Marketing Strategy Review', 13 | body: `Dear Team, 14 | 15 | I hope this email finds you well. Just a quick reminder about our Q1 Marketing Strategy meeting scheduled for tomorrow at 10 AM EST in Conference Room A. 16 | 17 | Agenda: 18 | - Q4 Performance Review 19 | - New Campaign Proposals 20 | - Budget Allocation for Q2 21 | - Team Resource Planning 22 | 23 | Please come prepared with your department updates. I've attached the preliminary deck for your review. 24 | 25 | Best regards, 26 | Alex Smith 27 | Senior Marketing Director 28 | Tel: (555) 123-4567`, 29 | date: new Date().toISOString() 30 | }, { 31 | id: 2, 32 | unread: true, 33 | from: { 34 | name: 'Jordan Brown', 35 | email: 'jordan.brown@example.com', 36 | avatar: { 37 | src: 'https://i.pravatar.cc/128?u=2' 38 | } 39 | }, 40 | subject: 'RE: Project Phoenix - Sprint 3 Update', 41 | body: `Hi team, 42 | 43 | Quick update on Sprint 3 deliverables: 44 | 45 | ✅ User authentication module completed 46 | 🏗️ Payment integration at 80% 47 | ⏳ API documentation pending review 48 | 49 | Key metrics: 50 | - Code coverage: 94% 51 | - Sprint velocity: 45 points 52 | - Bug resolution rate: 98% 53 | 54 | Please review the attached report for detailed analysis. Let's discuss any blockers in tomorrow's stand-up. 55 | 56 | Regards, 57 | Jordan 58 | 59 | -- 60 | Jordan Brown 61 | Lead Developer | Tech Solutions 62 | Mobile: +1 (555) 234-5678`, 63 | date: sub(new Date(), { minutes: 7 }).toISOString() 64 | }, { 65 | id: 3, 66 | unread: true, 67 | from: { 68 | name: 'Taylor Green', 69 | email: 'taylor.green@example.com', 70 | avatar: { 71 | src: 'https://i.pravatar.cc/128?u=3' 72 | } 73 | }, 74 | subject: 'Lunch Plans', 75 | body: `Hi there! 76 | 77 | I was wondering if you'd like to grab lunch this Friday? There's this amazing new Mexican restaurant downtown called "La Casa" that I've been wanting to try. They're known for their authentic tacos and house-made guacamole. 78 | 79 | Would 12:30 PM work for you? It would be great to catch up and discuss the upcoming team building event while we're there. 80 | 81 | Let me know what you think! 82 | 83 | Best, 84 | Taylor`, 85 | date: sub(new Date(), { hours: 3 }).toISOString() 86 | }, { 87 | id: 4, 88 | from: { 89 | name: 'Morgan White', 90 | email: 'morgan.white@example.com', 91 | avatar: { 92 | src: 'https://i.pravatar.cc/128?u=4' 93 | } 94 | }, 95 | subject: 'New Proposal: Project Horizon', 96 | body: `Hi team, 97 | 98 | I've just uploaded the comprehensive proposal for Project Horizon to our shared drive. The document includes: 99 | 100 | • Detailed project objectives and success metrics 101 | • Resource allocation and team structure 102 | • Timeline with key milestones 103 | • Budget breakdown 104 | • Risk assessment and mitigation strategies 105 | 106 | I'm particularly excited about our innovative approach to the user engagement component, which could set a new standard for our industry. 107 | 108 | Could you please review and provide feedback by EOD Friday? I'd like to present this to the steering committee next week. 109 | 110 | Thanks in advance, 111 | 112 | Morgan White 113 | Senior Project Manager 114 | Tel: (555) 234-5678`, 115 | date: sub(new Date(), { days: 1 }).toISOString() 116 | }, { 117 | id: 5, 118 | from: { 119 | name: 'Casey Gray', 120 | email: 'casey.gray@example.com' 121 | }, 122 | subject: 'Updated: San Francisco Conference Trip Itinerary', 123 | body: `Dear [Name], 124 | 125 | Please find your confirmed travel itinerary below: 126 | 127 | FLIGHT DETAILS: 128 | Outbound: AA 1234 129 | Date: March 15, 2024 130 | DEP: JFK 09:30 AM 131 | ARR: SFO 12:45 PM 132 | 133 | HOTEL: 134 | Marriott San Francisco 135 | Check-in: March 15 136 | Check-out: March 18 137 | Confirmation #: MR123456 138 | 139 | SCHEDULE: 140 | March 15 - Evening: Welcome Reception (6 PM) 141 | March 16 - Conference Day 1 (9 AM - 5 PM) 142 | March 17 - Conference Day 2 (9 AM - 4 PM) 143 | 144 | Please let me know if you need any modifications. 145 | 146 | Best regards, 147 | Casey Gray 148 | Travel Coordinator 149 | Office: (555) 345-6789`, 150 | date: sub(new Date(), { days: 1 }).toISOString() 151 | }, { 152 | id: 6, 153 | from: { 154 | name: 'Jamie Johnson', 155 | email: 'jamie.johnson@example.com' 156 | }, 157 | subject: 'Q1 2024 Financial Performance Review', 158 | body: `Dear Leadership Team, 159 | 160 | Please find attached our Q1 2024 financial analysis report. Key highlights: 161 | 162 | PERFORMANCE METRICS: 163 | • Revenue: $12.4M (+15% YoY) 164 | • Operating Expenses: $8.2M (-3% vs. budget) 165 | • Net Profit Margin: 18.5% (+2.5% vs. Q4 2023) 166 | 167 | AREAS OF OPTIMIZATION: 168 | 1. Cloud infrastructure costs (+22% over budget) 169 | 2. Marketing spend efficiency (-8% ROI vs. target) 170 | 3. Office operational costs (+5% vs. forecast) 171 | 172 | I've scheduled a detailed review for Thursday at 2 PM EST. Calendar invite to follow. 173 | 174 | Best regards, 175 | Jamie Johnson 176 | Chief Financial Officer 177 | Ext: 4567`, 178 | date: sub(new Date(), { days: 2 }).toISOString() 179 | }, { 180 | id: 7, 181 | from: { 182 | name: 'Riley Davis', 183 | email: 'riley.davis@example.com', 184 | avatar: { 185 | src: 'https://i.pravatar.cc/128?u=7' 186 | } 187 | }, 188 | subject: '[Mandatory] New DevOps Tools Training Session', 189 | body: `Hello Development Team, 190 | 191 | This is a reminder about next week's mandatory training session on our updated DevOps toolkit. 192 | 193 | 📅 Date: Tuesday, March 19 194 | ⏰ Time: 10:00 AM - 12:30 PM EST 195 | 📍 Location: Virtual (Zoom link below) 196 | 197 | We'll be covering: 198 | • GitLab CI/CD pipeline improvements 199 | • Docker container optimization 200 | • Kubernetes cluster management 201 | • New monitoring tools integration 202 | 203 | Prerequisites: 204 | 1. Install Docker Desktop 4.25 205 | 2. Update VS Code to latest version 206 | 3. Complete pre-training survey (link attached) 207 | 208 | Zoom Link: https://zoom.us/j/123456789 209 | Password: DevOps2024 210 | 211 | -- 212 | Riley Davis 213 | DevOps Lead 214 | Technical Operations 215 | M: (555) 777-8888`, 216 | date: sub(new Date(), { days: 2 }).toISOString() 217 | }, { 218 | id: 8, 219 | unread: true, 220 | from: { 221 | name: 'Kelly Wilson', 222 | email: 'kelly.wilson@example.com', 223 | avatar: { 224 | src: 'https://i.pravatar.cc/128?u=8' 225 | } 226 | }, 227 | subject: '🎉 Happy Birthday!', 228 | body: `Dear [Name], 229 | 230 | On behalf of the entire team, wishing you a fantastic birthday! 🎂 231 | 232 | We've organized a small celebration in the break room at 3 PM today. Cake and refreshments will be served! 233 | 234 | Your dedication and positive energy make our workplace better every day. Here's to another great year ahead! 235 | 236 | Best wishes, 237 | Kelly & The HR Team 238 | 239 | P.S. Don't forget to check your email for a special birthday surprise from the company! 🎁 240 | 241 | -- 242 | Kelly Wilson 243 | HR Director 244 | Human Resources Department 245 | Tel: (555) 999-0000`, 246 | date: sub(new Date(), { days: 2 }).toISOString() 247 | }, { 248 | id: 9, 249 | from: { 250 | name: 'Drew Moore', 251 | email: 'drew.moore@example.com' 252 | }, 253 | subject: 'Website Redesign Feedback Request - Phase 2', 254 | body: `Hi there, 255 | 256 | We're entering Phase 2 of our website redesign project and would value your input on the latest iterations. 257 | 258 | New Features Implementation: 259 | 1. Dynamic product catalog 260 | 2. Enhanced search functionality 261 | 3. Personalized user dashboard 262 | 4. Mobile-responsive navigation 263 | 264 | Review Links: 265 | • Staging Environment: https://staging.example.com 266 | • Design Specs: [Figma Link] 267 | • User Flow Documentation: [Confluence Link] 268 | 269 | Please provide feedback by EOD Friday. Key areas to focus on: 270 | - User experience 271 | - Navigation flow 272 | - Content hierarchy 273 | - Mobile responsiveness 274 | 275 | Your insights will be crucial for our final implementation decisions. 276 | 277 | Thanks in advance, 278 | Drew Moore 279 | UX Design Lead 280 | Product Design Team`, 281 | date: sub(new Date(), { days: 5 }).toISOString() 282 | }, { 283 | id: 10, 284 | from: { 285 | name: 'Jordan Taylor', 286 | email: 'jordan.taylor@example.com' 287 | }, 288 | subject: 'Corporate Wellness Program - Membership Renewal', 289 | body: `Dear Valued Member, 290 | 291 | Your corporate wellness program membership is due for renewal on April 1st, 2024. 292 | 293 | NEW AMENITIES: 294 | ✨ Expanded yoga studio 295 | 🏋️ State-of-the-art cardio equipment 296 | 🧘 Meditation room 297 | 👥 Additional group fitness classes 298 | 299 | RENEWAL BENEFITS: 300 | • 15% early bird discount 301 | • 3 complimentary personal training sessions 302 | • Free wellness assessment 303 | • Access to new mobile app 304 | 305 | To schedule a tour or discuss renewal options, please book a time here: [Booking Link] 306 | 307 | Stay healthy! 308 | 309 | Best regards, 310 | Jordan Taylor 311 | Corporate Wellness Coordinator 312 | Downtown Fitness Center 313 | Tel: (555) 123-7890`, 314 | date: sub(new Date(), { days: 5 }).toISOString() 315 | }, { 316 | id: 11, 317 | unread: true, 318 | from: { 319 | name: 'Morgan Anderson', 320 | email: 'morgan.anderson@example.com' 321 | }, 322 | subject: 'Important: Updates to Your Corporate Insurance Policy', 323 | body: `Dear [Employee Name], 324 | 325 | This email contains important information about changes to your corporate insurance coverage effective April 1, 2024. 326 | 327 | KEY UPDATES: 328 | 1. Health Insurance 329 | • Reduced co-pay for specialist visits ($35 → $25) 330 | • Extended telehealth coverage 331 | • New mental health benefits 332 | 333 | 2. Dental Coverage 334 | • Increased annual maximum ($1,500 → $2,000) 335 | • Added orthodontic coverage for dependents 336 | 337 | 3. Vision Benefits 338 | • Enhanced frame allowance 339 | • New LASIK discount program 340 | 341 | Please review the attached documentation carefully and complete the acknowledgment form by March 25th. 342 | 343 | Questions? Join our virtual info session: 344 | 📅 March 20th, 2024 345 | ⏰ 11:00 AM EST 346 | 🔗 [Teams Link] 347 | 348 | Regards, 349 | Morgan Anderson 350 | Benefits Coordinator 351 | HR Department`, 352 | date: sub(new Date(), { days: 12 }).toISOString() 353 | }, { 354 | id: 12, 355 | from: { 356 | name: 'Casey Thomas', 357 | email: 'casey.thomas@example.com' 358 | }, 359 | subject: '📚 March Book Club Meeting: "The Great Gatsby"', 360 | body: `Hello Book Lovers! 361 | 362 | I hope you're enjoying F. Scott Fitzgerald's masterpiece! Our next meeting details: 363 | 364 | 📅 Thursday, March 21st 365 | ⏰ 5:30 PM - 7:00 PM 366 | 📍 Main Conference Room (or Zoom) 367 | 368 | Discussion Topics: 369 | 1. Symbolism of the green light 370 | 2. The American Dream theme 371 | 3. Character development 372 | 4. Social commentary 373 | 374 | Please bring your suggestions for April's book selection! 375 | 376 | Refreshments will be provided 🍪 377 | 378 | RSVP by replying to this email. 379 | 380 | Happy reading! 381 | Casey 382 | 383 | -- 384 | Casey Thomas 385 | Book Club Coordinator 386 | Internal Culture Committee`, 387 | date: sub(new Date(), { months: 1 }).toISOString() 388 | }, { 389 | id: 13, 390 | from: { 391 | name: 'Jamie Jackson', 392 | email: 'jamie.jackson@example.com' 393 | }, 394 | subject: '🍳 Company Cookbook Project - Recipe Submission Reminder', 395 | body: `Dear Colleagues, 396 | 397 | Final call for our company cookbook project submissions! 398 | 399 | Guidelines for Recipe Submission: 400 | 1. Include ingredients list with measurements 401 | 2. Step-by-step instructions 402 | 3. Cooking time and servings 403 | 4. Photo of the finished dish (optional) 404 | 5. Any cultural or personal significance 405 | 406 | Submission Deadline: March 22nd, 2024 407 | 408 | We already have some amazing entries: 409 | • Sarah's Famous Chili 410 | • Mike's Mediterranean Pasta 411 | • Lisa's Vegan Brownies 412 | • Tom's Family Paella 413 | 414 | All proceeds from cookbook sales will support our local food bank. 415 | 416 | Submit here: [Form Link] 417 | 418 | Cooking together, 419 | Jamie Jackson 420 | Community Engagement Committee 421 | Ext. 5432`, 422 | date: sub(new Date(), { months: 1 }).toISOString() 423 | }, { 424 | id: 14, 425 | from: { 426 | name: 'Riley White', 427 | email: 'riley.white@example.com' 428 | }, 429 | subject: '🧘‍♀️ Updated Corporate Wellness Schedule - Spring 2024', 430 | body: `Dear Wellness Program Participants, 431 | 432 | Our Spring 2024 wellness schedule is now available! 433 | 434 | NEW CLASSES: 435 | Monday: 436 | • 7:30 AM - Morning Flow Yoga 437 | • 12:15 PM - HIIT Express 438 | • 5:30 PM - Meditation Basics 439 | 440 | Wednesday: 441 | • 8:00 AM - Power Vinyasa 442 | • 12:00 PM - Desk Stretching 443 | • 4:30 PM - Mindfulness Workshop 444 | 445 | Friday: 446 | • 7:45 AM - Gentle Yoga 447 | • 12:30 PM - Stress Management 448 | • 4:45 PM - Weekend Wind-Down 449 | 450 | All classes available in-person and via Zoom. 451 | Download our app to reserve your spot! 452 | 453 | Namaste, 454 | Riley White 455 | Corporate Wellness Instructor 456 | Wellness & Benefits Team`, 457 | date: sub(new Date(), { months: 1 }).toISOString() 458 | }, { 459 | id: 15, 460 | from: { 461 | name: 'Kelly Harris', 462 | email: 'kelly.harris@example.com' 463 | }, 464 | subject: '📚 Book Launch Event: "Digital Transformation in the Modern Age"', 465 | body: `Dear [Name], 466 | 467 | You're cordially invited to the launch of my new book, "Digital Transformation in the Modern Age: A Leadership Guide" 468 | 469 | EVENT DETAILS: 470 | 📅 Date: April 15th, 2024 471 | ⏰ Time: 6:00 PM - 8:30 PM EST 472 | 📍 Grand Hotel Downtown 473 | 123 Business Ave. 474 | 475 | AGENDA: 476 | 6:00 PM - Welcome Reception 477 | 6:30 PM - Keynote Presentation 478 | 7:15 PM - Q&A Session 479 | 7:45 PM - Book Signing 480 | 8:00 PM - Networking 481 | 482 | Light refreshments will be served. 483 | Each attendee will receive a signed copy of the book. 484 | 485 | RSVP by April 1st: [Event Link] 486 | 487 | Looking forward to sharing this milestone with you! 488 | 489 | Best regards, 490 | Kelly Harris 491 | Digital Strategy Consultant 492 | Author, "Digital Transformation in the Modern Age"`, 493 | date: sub(new Date(), { months: 1 }).toISOString() 494 | }, { 495 | id: 16, 496 | from: { 497 | name: 'Drew Martin', 498 | email: 'drew.martin@example.com' 499 | }, 500 | subject: '🚀 TechCon 2024: Early Bird Registration Now Open', 501 | body: `Dear Tech Enthusiasts, 502 | 503 | Registration is now open for TechCon 2024: "Innovation at Scale" 504 | 505 | CONFERENCE HIGHLIGHTS: 506 | 📅 May 15-17, 2024 507 | 📍 Tech Convention Center 508 | 509 | KEYNOTE SPEAKERS: 510 | • Sarah Johnson - CEO, Future Tech Inc. 511 | • Dr. Michael Chang - AI Research Director 512 | • Lisa Rodriguez - Cybersecurity Expert 513 | 514 | TRACKS: 515 | 1. AI/ML Innovation 516 | 2. Cloud Architecture 517 | 3. DevSecOps 518 | 4. Digital Transformation 519 | 5. Emerging Technologies 520 | 521 | EARLY BIRD PRICING (ends April 1): 522 | Full Conference Pass: $899 (reg. $1,199) 523 | Team Discount (5+): 15% off 524 | 525 | Register here: [Registration Link] 526 | 527 | Best regards, 528 | Drew Martin 529 | Conference Director 530 | TechCon 2024`, 531 | date: sub(new Date(), { months: 1, days: 4 }).toISOString() 532 | }, { 533 | id: 17, 534 | from: { 535 | name: 'Alex Thompson', 536 | email: 'alex.thompson@example.com' 537 | }, 538 | subject: '🎨 Modern Perspectives: Contemporary Art Exhibition', 539 | body: `Hi there, 540 | 541 | Hope you're well! I wanted to personally invite you to an extraordinary art exhibition this weekend. 542 | 543 | "Modern Perspectives: Breaking Boundaries" 544 | 📅 Saturday & Sunday 545 | ⏰ 10 AM - 6 PM 546 | 📍 Metropolitan Art Gallery 547 | 548 | FEATURED ARTISTS: 549 | • Maria Chen - Mixed Media 550 | • James Wright - Digital Art 551 | • Sofia Patel - Installation 552 | • Robert Kim - Photography 553 | 554 | SPECIAL EVENTS: 555 | • Artist Talk: Saturday, 2 PM 556 | • Workshop: Sunday, 11 AM 557 | • Wine Reception: Saturday, 5 PM 558 | 559 | Would love to meet you there! Let me know if you'd like to go together. 560 | 561 | Best, 562 | Alex Thompson 563 | Curator 564 | Metropolitan Art Gallery 565 | Tel: (555) 234-5678`, 566 | date: sub(new Date(), { months: 1, days: 15 }).toISOString() 567 | }, { 568 | id: 18, 569 | from: { 570 | name: 'Jordan Garcia', 571 | email: 'jordan.garcia@example.com' 572 | }, 573 | subject: '🤝 Industry Networking Event: "Connect & Innovate 2024"', 574 | body: `Dear Professional Network, 575 | 576 | You're invited to our premier networking event! 577 | 578 | EVENT DETAILS: 579 | 📅 March 28th, 2024 580 | ⏰ 6:00 PM - 9:00 PM 581 | 📍 Innovation Hub 582 | 456 Enterprise Street 583 | 584 | SPEAKERS: 585 | • Mark Thompson - "Future of Work" 586 | • Dr. Sarah Chen - "Innovation Trends" 587 | • Robert Mills - "Digital Leadership" 588 | 589 | SCHEDULE: 590 | 6:00 - Registration & Welcome 591 | 6:30 - Keynote Presentations 592 | 7:30 - Networking Session 593 | 8:30 - Panel Discussion 594 | 595 | Complimentary hors d'oeuvres and beverages will be served. 596 | 597 | RSVP Required: [Registration Link] 598 | 599 | Best regards, 600 | Jordan Garcia 601 | Event Coordinator 602 | Professional Networking Association`, 603 | date: sub(new Date(), { months: 1, days: 18 }).toISOString() 604 | }, { 605 | id: 19, 606 | from: { 607 | name: 'Taylor Rodriguez', 608 | email: 'taylor.rodriguez@example.com' 609 | }, 610 | subject: '🌟 Community Service Day - Volunteer Opportunities', 611 | body: `Dear Colleagues, 612 | 613 | Join us for our annual Community Service Day! 614 | 615 | EVENT DETAILS: 616 | 📅 Saturday, April 6th, 2024 617 | ⏰ 9:00 AM - 3:00 PM 618 | 📍 Multiple Locations 619 | 620 | VOLUNTEER OPPORTUNITIES: 621 | 1. City Park Cleanup 622 | • Garden maintenance 623 | • Trail restoration 624 | • Playground repair 625 | 626 | 2. Food Bank 627 | • Sorting donations 628 | • Packing meals 629 | • Distribution 630 | 631 | 3. Animal Shelter 632 | • Dog walking 633 | • Facility cleaning 634 | • Social media support 635 | 636 | All volunteers receive: 637 | • Company volunteer t-shirt 638 | • Lunch and refreshments 639 | • Certificate of participation 640 | • 8 hours community service credit 641 | 642 | Sign up here: [Volunteer Portal] 643 | 644 | Making a difference together, 645 | Taylor Rodriguez 646 | Community Outreach Coordinator 647 | Corporate Social Responsibility Team`, 648 | date: sub(new Date(), { months: 1, days: 25 }).toISOString() 649 | }, { 650 | id: 20, 651 | from: { 652 | name: 'Morgan Lopez', 653 | email: 'morgan.lopez@example.com' 654 | }, 655 | subject: '🚗 Vehicle Maintenance Reminder: 30,000 Mile Service', 656 | body: `Dear Valued Customer, 657 | 658 | Your vehicle is due for its 30,000-mile maintenance service. 659 | 660 | RECOMMENDED SERVICES: 661 | • Oil and filter change 662 | • Tire rotation and alignment 663 | • Brake system inspection 664 | • Multi-point safety inspection 665 | • Fluid level check and top-off 666 | • Battery performance test 667 | 668 | SERVICE CENTER DETAILS: 669 | 📍 Downtown Auto Care 670 | 789 Service Road 671 | 672 | ☎️ (555) 987-6543 673 | 674 | Available Appointments: 675 | • Monday-Friday: 7:30 AM - 6:00 PM 676 | • Saturday: 8:00 AM - 2:00 PM 677 | 678 | Schedule online: [Booking Link] 679 | or call our service desk directly. 680 | 681 | Drive safely, 682 | Morgan Lopez 683 | Service Coordinator 684 | Downtown Auto Care 685 | Emergency: (555) 987-6544`, 686 | date: sub(new Date(), { months: 2 }).toISOString() 687 | }] 688 | 689 | export default eventHandler(async () => { 690 | return mails 691 | }) 692 | -------------------------------------------------------------------------------- /server/api/members.ts: -------------------------------------------------------------------------------- 1 | const members = [{ 2 | name: 'Anthony Fu', 3 | username: 'antfu', 4 | role: 'member', 5 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/antfu' } 6 | }, { 7 | name: 'Baptiste Leproux', 8 | username: 'larbish', 9 | role: 'member', 10 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/larbish' } 11 | }, { 12 | name: 'Benjamin Canac', 13 | username: 'benjamincanac', 14 | role: 'owner', 15 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/benjamincanac' } 16 | }, { 17 | name: 'Céline Dumerc', 18 | username: 'celinedumerc', 19 | role: 'member', 20 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/celinedumerc' } 21 | }, { 22 | name: 'Daniel Roe', 23 | username: 'danielroe', 24 | role: 'member', 25 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/danielroe' } 26 | }, { 27 | name: 'Farnabaz', 28 | username: 'farnabaz', 29 | role: 'member', 30 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/farnabaz' } 31 | }, { 32 | name: 'Ferdinand Coumau', 33 | username: 'FerdinandCoumau', 34 | role: 'member', 35 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/FerdinandCoumau' } 36 | }, { 37 | name: 'Hugo Richard', 38 | username: 'hugorcd', 39 | role: 'owner', 40 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/hugorcd' } 41 | }, { 42 | name: 'Pooya Parsa', 43 | username: 'pi0', 44 | role: 'member', 45 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/pi0' } 46 | }, { 47 | name: 'Sarah Moriceau', 48 | username: 'SarahM19', 49 | role: 'member', 50 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/SarahM19' } 51 | }, { 52 | name: 'Sébastien Chopin', 53 | username: 'Atinux', 54 | role: 'owner', 55 | avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/atinux' } 56 | }] 57 | 58 | export default eventHandler(async () => { 59 | return members 60 | }) 61 | -------------------------------------------------------------------------------- /server/api/notifications.ts: -------------------------------------------------------------------------------- 1 | import { sub } from 'date-fns' 2 | 3 | const notifications = [{ 4 | id: 1, 5 | unread: true, 6 | sender: { 7 | name: 'Jordan Brown', 8 | email: 'jordan.brown@example.com', 9 | avatar: { 10 | src: 'https://i.pravatar.cc/128?u=2' 11 | } 12 | }, 13 | body: 'sent you a message', 14 | date: sub(new Date(), { minutes: 7 }).toISOString() 15 | }, { 16 | id: 2, 17 | sender: { 18 | name: 'Lindsay Walton' 19 | }, 20 | body: 'subscribed to your email list', 21 | date: sub(new Date(), { hours: 1 }).toISOString() 22 | }, { 23 | id: 3, 24 | unread: true, 25 | sender: { 26 | name: 'Taylor Green', 27 | email: 'taylor.green@example.com', 28 | avatar: { 29 | src: 'https://i.pravatar.cc/128?u=3' 30 | } 31 | }, 32 | body: 'sent you a message', 33 | date: sub(new Date(), { hours: 3 }).toISOString() 34 | }, { 35 | id: 4, 36 | sender: { 37 | name: 'Courtney Henry', 38 | avatar: { 39 | src: 'https://i.pravatar.cc/128?u=4' 40 | } 41 | }, 42 | body: 'added you to a project', 43 | date: sub(new Date(), { hours: 3 }).toISOString() 44 | }, { 45 | id: 5, 46 | sender: { 47 | name: 'Tom Cook', 48 | avatar: { 49 | src: 'https://i.pravatar.cc/128?u=5' 50 | } 51 | }, 52 | body: 'abandonned cart', 53 | date: sub(new Date(), { hours: 7 }).toISOString() 54 | }, { 55 | id: 6, 56 | sender: { 57 | name: 'Casey Thomas', 58 | avatar: { 59 | src: 'https://i.pravatar.cc/128?u=6' 60 | } 61 | }, 62 | body: 'purchased your product', 63 | date: sub(new Date(), { days: 1, hours: 3 }).toISOString() 64 | }, { 65 | id: 7, 66 | unread: true, 67 | sender: { 68 | name: 'Kelly Wilson', 69 | email: 'kelly.wilson@example.com', 70 | avatar: { 71 | src: 'https://i.pravatar.cc/128?u=8' 72 | } 73 | }, 74 | body: 'sent you a message', 75 | date: sub(new Date(), { days: 2 }).toISOString() 76 | }, { 77 | id: 8, 78 | sender: { 79 | name: 'Jamie Johnson', 80 | email: 'jamie.johnson@example.com', 81 | avatar: { 82 | src: 'https://i.pravatar.cc/128?u=9' 83 | } 84 | }, 85 | body: 'requested a refund', 86 | date: sub(new Date(), { days: 5, hours: 4 }).toISOString() 87 | }, { 88 | id: 9, 89 | unread: true, 90 | sender: { 91 | name: 'Morgan Anderson', 92 | email: 'morgan.anderson@example.com' 93 | }, 94 | body: 'sent you a message', 95 | date: sub(new Date(), { days: 6 }).toISOString() 96 | }, { 97 | id: 10, 98 | sender: { 99 | name: 'Drew Moore' 100 | }, 101 | body: 'subscribed to your email list', 102 | date: sub(new Date(), { days: 6 }).toISOString() 103 | }, { 104 | id: 11, 105 | sender: { 106 | name: 'Riley Davis' 107 | }, 108 | body: 'abandonned cart', 109 | date: sub(new Date(), { days: 7 }).toISOString() 110 | }, { 111 | id: 12, 112 | sender: { 113 | name: 'Jordan Taylor' 114 | }, 115 | body: 'subscribed to your email list', 116 | date: sub(new Date(), { days: 9 }).toISOString() 117 | }, { 118 | id: 13, 119 | sender: { 120 | name: 'Kelly Wilson', 121 | email: 'kelly.wilson@example.com', 122 | avatar: { 123 | src: 'https://i.pravatar.cc/128?u=8' 124 | } 125 | }, 126 | body: 'subscribed to your email list', 127 | date: sub(new Date(), { days: 10 }).toISOString() 128 | }, { 129 | id: 14, 130 | sender: { 131 | name: 'Jamie Johnson', 132 | email: 'jamie.johnson@example.com', 133 | avatar: { 134 | src: 'https://i.pravatar.cc/128?u=9' 135 | } 136 | }, 137 | body: 'subscribed to your email list', 138 | date: sub(new Date(), { days: 11 }).toISOString() 139 | }, { 140 | id: 15, 141 | sender: { 142 | name: 'Morgan Anderson' 143 | }, 144 | body: 'purchased your product', 145 | date: sub(new Date(), { days: 12 }).toISOString() 146 | }, { 147 | id: 16, 148 | sender: { 149 | name: 'Drew Moore', 150 | avatar: { 151 | src: 'https://i.pravatar.cc/128?u=16' 152 | } 153 | }, 154 | body: 'subscribed to your email list', 155 | date: sub(new Date(), { days: 13 }).toISOString() 156 | }, { 157 | id: 17, 158 | sender: { 159 | name: 'Riley Davis' 160 | }, 161 | body: 'subscribed to your email list', 162 | date: sub(new Date(), { days: 14 }).toISOString() 163 | }, { 164 | id: 18, 165 | sender: { 166 | name: 'Jordan Taylor' 167 | }, 168 | body: 'subscribed to your email list', 169 | date: sub(new Date(), { days: 15 }).toISOString() 170 | }, { 171 | id: 19, 172 | sender: { 173 | name: 'Kelly Wilson', 174 | email: 'kelly.wilson@example.com', 175 | avatar: { 176 | src: 'https://i.pravatar.cc/128?u=8' 177 | } 178 | }, 179 | body: 'subscribed to your email list', 180 | date: sub(new Date(), { days: 16 }).toISOString() 181 | }, { 182 | id: 20, 183 | sender: { 184 | name: 'Jamie Johnson', 185 | email: 'jamie.johnson@example.com', 186 | avatar: { 187 | src: 'https://i.pravatar.cc/128?u=9' 188 | } 189 | }, 190 | body: 'purchased your product', 191 | date: sub(new Date(), { days: 17 }).toISOString() 192 | }, { 193 | id: 21, 194 | sender: { 195 | name: 'Morgan Anderson' 196 | }, 197 | body: 'abandonned cart', 198 | date: sub(new Date(), { days: 17 }).toISOString() 199 | }, { 200 | id: 22, 201 | sender: { 202 | name: 'Drew Moore' 203 | }, 204 | body: 'subscribed to your email list', 205 | date: sub(new Date(), { days: 18 }).toISOString() 206 | }, { 207 | id: 23, 208 | sender: { 209 | name: 'Riley Davis' 210 | }, 211 | body: 'subscribed to your email list', 212 | date: sub(new Date(), { days: 19 }).toISOString() 213 | }, { 214 | id: 24, 215 | sender: { 216 | name: 'Jordan Taylor', 217 | avatar: { 218 | src: 'https://i.pravatar.cc/128?u=24' 219 | } 220 | }, 221 | body: 'subscribed to your email list', 222 | date: sub(new Date(), { days: 20 }).toISOString() 223 | }, { 224 | id: 25, 225 | sender: { 226 | name: 'Kelly Wilson', 227 | email: 'kelly.wilson@example.com', 228 | avatar: { 229 | src: 'https://i.pravatar.cc/128?u=8' 230 | } 231 | }, 232 | body: 'subscribed to your email list', 233 | date: sub(new Date(), { days: 20 }).toISOString() 234 | }, { 235 | id: 26, 236 | sender: { 237 | name: 'Jamie Johnson', 238 | email: 'jamie.johnson@example.com', 239 | avatar: { 240 | src: 'https://i.pravatar.cc/128?u=9' 241 | } 242 | }, 243 | body: 'abandonned cart', 244 | date: sub(new Date(), { days: 21 }).toISOString() 245 | }, { 246 | id: 27, 247 | sender: { 248 | name: 'Morgan Anderson' 249 | }, 250 | body: 'subscribed to your email list', 251 | date: sub(new Date(), { days: 22 }).toISOString() 252 | }] 253 | 254 | export default eventHandler(async () => { 255 | return notifications 256 | }) 257 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | --------------------------------------------------------------------------------