feat: подготовил дизайн (изменения из другого репозитория)
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 5s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 8s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 3s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 5s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 8s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 3s
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import GlassCard from '@/components/ui/GlassCard.vue'
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
const grouped = computed(() => {
|
||||
const map: Record<string, typeof userStore.notifications> = {}
|
||||
userStore.notifications.forEach(n => {
|
||||
const day = new Date(n.createdAt).toLocaleDateString('ru-RU')
|
||||
map[day] = map[day] || []
|
||||
map[day].push(n)
|
||||
})
|
||||
return Object.entries(map)
|
||||
})
|
||||
|
||||
const typeIcon: Record<string, string> = {
|
||||
reminder: '⏰',
|
||||
'schedule-change': '🗓️',
|
||||
achievement: '🏆',
|
||||
coins: '💰',
|
||||
recommendation: '✨',
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="notifications page-content">
|
||||
<div class="header">
|
||||
<h1 class="page-title">Уведомления</h1>
|
||||
<button class="btn-secondary" @click="userStore.markAllRead">Отметить все как прочитанные</button>
|
||||
</div>
|
||||
|
||||
<div class="notification-groups">
|
||||
<GlassCard v-for="([day, items]) in grouped" :key="day" class="group">
|
||||
<div class="group-title">{{ day }}</div>
|
||||
<div class="items">
|
||||
<div v-for="n in items" :key="n.id" class="item" :class="{ unread: !n.read }">
|
||||
<div class="icon">{{ typeIcon[n.type] }}</div>
|
||||
<div>
|
||||
<div class="item-title">{{ n.title }}</div>
|
||||
<div class="item-body">{{ n.body }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.notifications { display: flex; flex-direction: column; gap: 18px; }
|
||||
.header { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
|
||||
.notification-groups { display: flex; flex-direction: column; gap: 14px; }
|
||||
.group-title { font-weight: 700; margin-bottom: 10px; }
|
||||
.items { display: flex; flex-direction: column; gap: 10px; }
|
||||
.item { display: flex; gap: 12px; padding: 10px; border-radius: var(--radius-sm); background: rgba(255,255,255,0.6); border: 1px solid var(--color-border-glass); }
|
||||
.item.unread { border-color: rgba(34,197,94,0.4); background: rgba(34,197,94,0.08); }
|
||||
.icon { font-size: 20px; }
|
||||
.item-title { font-weight: 600; }
|
||||
.item-body { font-size: 13px; color: var(--color-text-secondary); }
|
||||
</style>
|
||||
Reference in New Issue
Block a user