Port modular app notifications, pargar date display, and closed-store product UX.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-25 16:29:33 +02:00
co-authored by Cursor
parent 4fd12277e7
commit e6dea15752
33 changed files with 1253 additions and 47 deletions
+56 -1
View File
@@ -10,6 +10,20 @@
</div>
<div class="flex items-center gap-2">
<button
v-if="notificationEnabled"
type="button"
class="mhome-header-btn mhome-header-btn--notify"
aria-label="اعلان"
@click.stop="goNotifications"
>
<span class="mhome-header-btn__icon-wrap">
<Icon icon="vuesax-linear:notification-bing" size="18" />
<span v-if="unreadCount > 0" class="mhome-header-btn__badge">
{{ unreadCount > 99 ? '99+' : unreadCount }}
</span>
</span>
</button>
<button
type="button"
class="mhome-header-btn"
@@ -36,12 +50,27 @@ import { useRoute } from 'vue-router'
import router from '@/router'
import Icon from '@/components/BasicPacks/BasicIcon.vue'
import { getProjectMobileNavLogo } from '@/utils/config'
import { useAppNotificationBadge } from '@/composables/useAppNotificationBadge'
import { canRequestBrowserNotification, requestBrowserNotificationPermission } from '@/utils/browserNotification'
const headerRef = ref<HTMLElement | null>(null)
const isHeaderScrolled = ref(false)
const route = useRoute()
const projectLogo = computed(() => getProjectMobileNavLogo())
const {
enabled: notificationEnabled,
unreadCount,
clearUnreadLocally,
} = useAppNotificationBadge()
async function goNotifications() {
clearUnreadLocally()
if (canRequestBrowserNotification()) {
await requestBrowserNotificationPermission()
}
void router.push({ name: 'appNotifications' })
}
let intersectionObserver: IntersectionObserver | null = null
let scrollTarget: HTMLElement | Window | null = null
@@ -177,7 +206,7 @@ defineEmits<{
.app-header {
z-index: 1999;
box-sizing: border-box;
padding-top: calc(0.5rem + var(--app-safe-top, env(safe-area-inset-top, 0px)));
padding-top: calc(0.5rem + var(--app-safe-top, 0px));
background-color: transparent;
}
@@ -209,4 +238,30 @@ defineEmits<{
border-color: #fecaca;
background: #fef2f2;
}
.mhome-header-btn--notify {
color: #0a1b37;
border-color: #e5e7eb;
background: #fff;
}
.mhome-header-btn__icon-wrap {
@apply relative inline-flex;
}
.mhome-header-btn__badge {
position: absolute;
top: -8px;
left: -8px;
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 999px;
background: #dc2626;
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 16px;
text-align: center;
}
</style>
@@ -10,6 +10,24 @@
<BasicIcon icon="vuesax-linear:user" size="16" />
<span>حساب کاربری</span>
</button>
<button
v-if="notificationEnabled"
type="button"
class="dhome-btn-ghost dhome-btn-ghost--notify"
aria-label="اعلان"
@click="goNotifications"
>
<span class="dhome-notify-wrap">
<BasicIcon icon="vuesax-linear:notification-bing" size="16" />
<span v-if="unreadCount > 0" class="dhome-notify-badge">
{{ unreadCount > 99 ? '99+' : unreadCount }}
</span>
</span>
<span>اعلان</span>
</button>
<button type="button" class="dhome-btn-ghost" aria-label="بروزرسانی" @click="reloadApp">
<BasicIcon icon="vuesax-linear:refresh-2" size="16" />
</button>
<button
v-if="showLogout"
type="button"
@@ -26,6 +44,8 @@
<script lang="ts" setup>
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
import { useUserStore } from '@/store/userStore'
import { useAppNotificationBadge } from '@/composables/useAppNotificationBadge'
import { canRequestBrowserNotification, requestBrowserNotificationPermission } from '@/utils/browserNotification'
import router from '@/router'
withDefaults(
@@ -40,4 +60,43 @@ defineEmits<{
}>()
const userStore = useUserStore()
const {
enabled: notificationEnabled,
unreadCount,
clearUnreadLocally,
} = useAppNotificationBadge()
async function goNotifications() {
clearUnreadLocally()
if (canRequestBrowserNotification()) {
await requestBrowserNotificationPermission()
}
void router.push({ name: 'appNotifications' })
}
function reloadApp() {
window.location.reload()
}
</script>
<style scoped>
.dhome-notify-wrap {
position: relative;
display: inline-flex;
}
.dhome-notify-badge {
position: absolute;
top: -8px;
left: -8px;
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 999px;
background: #dc2626;
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 16px;
text-align: center;
}
</style>