Files
material-kit-design/src/views/NotificationsView.vue
T
2026-06-01 16:30:02 -06:00

111 lines
4.3 KiB
Vue

<script setup>
import { ref } from 'vue'
import DashboardLayout from '../layouts/DashboardLayout.vue'
const dismissed = ref(new Set())
const alerts = [
{ id: 1, type: 'success', icon: 'check_circle', title: 'Success', message: 'This is a success notification — something went well.' },
{ id: 2, type: 'info', icon: 'info', title: 'Info', message: 'This is an info notification — just letting you know.' },
{ id: 3, type: 'warning', icon: 'warning', title: 'Warning', message: 'This is a warning notification — you should take action.' },
{ id: 4, type: 'danger', icon: 'error', title: 'Error', message: 'This is an error notification — something went wrong.' },
]
const typeStyle = {
success: 'bg-success text-white',
info: 'bg-info text-white',
warning: 'bg-warning text-white',
danger: 'bg-danger text-white',
}
const notifications = [
{ id: 10, avatar: 'PC', color: 'primary', name: 'Patrick Collins', time: '13 minutes ago', text: 'New message in Design System channel' },
{ id: 11, avatar: 'MR', color: 'info', name: 'Mikaela Ramos', time: '2 hours ago', text: 'Updated the icon grid component' },
{ id: 12, avatar: 'TP', color: 'success', name: 'Tom Perez', time: 'Yesterday', text: 'Released v0.2.0 with table improvements' },
{ id: 13, avatar: 'LC', color: 'warning', name: 'Lacina Cosmo', time: '2 days ago', text: 'Flagged a responsiveness issue on mobile' },
{ id: 14, avatar: 'AM', color: 'danger', name: 'Ally Maria', time: 'Last week', text: 'Added font preload entries to index.html' },
]
function dismiss(id) {
dismissed.value.add(id)
}
</script>
<template>
<DashboardLayout>
<div class="grid gap-6 lg:grid-cols-2">
<!-- Dismissible alerts -->
<div class="rounded-2xl bg-white p-6 shadow-soft-md">
<h6 class="mb-1 text-sm font-bold text-dark">Alert States</h6>
<p class="mb-6 text-xs text-secondary">Dismissible alerts for each semantic color</p>
<div class="space-y-3">
<transition-group name="alert">
<div
v-for="alert in alerts"
v-show="!dismissed.has(alert.id)"
:key="alert.id"
class="flex items-start gap-3 rounded-lg p-4 text-sm font-medium"
:class="typeStyle[alert.type]"
>
<span class="material-icons text-lg leading-none shrink-0">{{ alert.icon }}</span>
<p class="flex-1">
<span class="font-bold">{{ alert.title }} </span>{{ alert.message }}
</p>
<button
class="shrink-0 opacity-70 hover:opacity-100 transition-opacity"
@click="dismiss(alert.id)"
>
<span class="material-icons text-lg leading-none">close</span>
</button>
</div>
</transition-group>
</div>
</div>
<!-- Notification feed -->
<div class="rounded-2xl bg-white p-6 shadow-soft-md">
<div class="mb-6 flex items-center justify-between">
<h6 class="text-sm font-bold text-dark">Recent Notifications</h6>
<span class="rounded-full bg-primary/10 px-2.5 py-1 text-xs font-medium text-primary">
{{ notifications.length }} new
</span>
</div>
<div class="space-y-4">
<div
v-for="n in notifications"
:key="n.id"
class="flex items-start gap-3"
>
<div
class="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl text-xs font-bold text-white shadow-soft-sm"
:class="`bg-gradient-${n.color} shadow-${n.color}`"
>
{{ n.avatar }}
</div>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-dark truncate">{{ n.name }}</p>
<p class="text-xs text-secondary mt-0.5">{{ n.text }}</p>
</div>
<span class="shrink-0 text-xs text-secondary">{{ n.time }}</span>
</div>
</div>
</div>
</div>
</DashboardLayout>
</template>
<style scoped>
.alert-leave-active {
transition: all 0.3s ease;
}
.alert-leave-to {
opacity: 0;
transform: translateX(1rem);
max-height: 0;
margin: 0;
padding: 0;
}
</style>