HR-ATS-Portal/frontend/src/api/notifications.js

64 lines
1.8 KiB
JavaScript

import { request } from '../lib/apiClient'
import { toDate } from '../lib/format'
/** In-app notifications — backend/notifications/app.py. Scoped to the caller; no RBAC tag. */
const KIND_META = {
application: { icon: 'user-plus', color: 'i-green' },
interview: { icon: 'calendar', color: 'i-blue' },
offer: { icon: 'check', color: 'i-teal' },
assessment: { icon: 'star', color: 'i-amber' },
approval: { icon: 'file', color: 'i-indigo' },
message: { icon: 'message', color: 'i-purple' },
system: { icon: 'info', color: 'i-gray' },
}
export function list({ unreadOnly, top, skip } = {}) {
return request('/notifications/fetch', {
params: { unread_only: unreadOnly, top, skip },
})
}
export function markRead(recordId) {
return request(`/notifications/${recordId}/read`, { method: 'POST' })
}
export function markAllRead() {
return request('/notifications/read-all', { method: 'POST' })
}
export function remove(recordId) {
return request('/notifications/delete', {
method: 'DELETE',
params: { record_id: recordId },
})
}
function relTime(iso) {
if (!iso) return ''
const then = toDate(iso)
if (!then) return ''
const mins = Math.max(0, Math.round((Date.now() - then.getTime()) / 60000))
if (mins < 60) return `${mins}m ago`
if (mins < 1440) return `${Math.floor(mins / 60)}h ago`
return `${Math.floor(mins / 1440)}d ago`
}
export function toNotificationView(row) {
const meta = KIND_META[row.kind] || KIND_META.system
return {
id: row.id,
kind: row.kind,
title: row.title,
text: row.body || '',
linkPath: row.link_path || null,
inboxId: row.inbox_id,
jobPostId: row.job_post_id,
unread: !row.is_read,
time: relTime(row.created_at),
createdAt: row.created_at,
icon: meta.icon,
color: meta.color,
}
}