NotificationDetail.tsx114 lines · main
| 1 | import { Archive, ArchiveRestoreIcon, ExternalLink } from 'lucide-react' |
| 2 | import Link from 'next/link' |
| 3 | import { Button } from 'ui' |
| 4 | |
| 5 | import { Markdown } from '@/components/interfaces/Markdown' |
| 6 | import { Notification, NotificationData } from '@/data/notifications/notifications-v2-query' |
| 7 | import { useOrganizationsQuery } from '@/data/organizations/organizations-query' |
| 8 | import { useProjectDetailQuery } from '@/data/projects/project-detail-query' |
| 9 | |
| 10 | interface NotificationDetailProps { |
| 11 | notification: Notification |
| 12 | onUpdateStatus: (id: string, status: 'archived' | 'seen') => void |
| 13 | } |
| 14 | |
| 15 | export const NotificationDetail = ({ notification, onUpdateStatus }: NotificationDetailProps) => { |
| 16 | const data = notification.data as NotificationData |
| 17 | |
| 18 | const { data: project } = useProjectDetailQuery({ ref: data.project_ref }) |
| 19 | const { data: organizations } = useOrganizationsQuery() |
| 20 | |
| 21 | const organization = |
| 22 | data.org_slug !== undefined |
| 23 | ? organizations?.find((org) => org.slug === data.org_slug) |
| 24 | : project !== undefined |
| 25 | ? organizations?.find((org) => org.id === project.organization_id) |
| 26 | : undefined |
| 27 | |
| 28 | const onButtonAction = (type?: string) => { |
| 29 | // [Joshen] Implement accordingly - BE team will need to give us a heads up on this |
| 30 | console.log('Action', type) |
| 31 | } |
| 32 | |
| 33 | return ( |
| 34 | <div> |
| 35 | {(project !== undefined || organization !== undefined) && ( |
| 36 | <> |
| 37 | <h3 className="text-sm mb-2">Context</h3> |
| 38 | <div className="flex items-center gap-2 flex-wrap mb-6"> |
| 39 | {organization !== undefined && ( |
| 40 | <Link |
| 41 | title={organization.name} |
| 42 | href={`/org/${organization.slug}/general`} |
| 43 | className="text-link" |
| 44 | > |
| 45 | {organization.name} |
| 46 | </Link> |
| 47 | )} |
| 48 | {project !== undefined && ( |
| 49 | <Link title={project.name} href={`/project/${project.ref}`} className="text-link"> |
| 50 | {project.name} |
| 51 | </Link> |
| 52 | )} |
| 53 | </div> |
| 54 | </> |
| 55 | )} |
| 56 | |
| 57 | {data.message !== undefined && ( |
| 58 | <> |
| 59 | <h3 className="text-sm mb-2">Message</h3> |
| 60 | <Markdown |
| 61 | className="leading-6 text-sm text-foreground-light mb-6" |
| 62 | content={data.message} |
| 63 | /> |
| 64 | </> |
| 65 | )} |
| 66 | |
| 67 | <h3 className="text-sm mb-2">Actions</h3> |
| 68 | <div className="flex items-center gap-2"> |
| 69 | {(data.actions ?? []).map((action, idx) => { |
| 70 | const key = `${notification.id}-action-${idx}` |
| 71 | if (action.url !== undefined) { |
| 72 | const url = action.url.includes('[ref]') |
| 73 | ? action.url.replace('[ref]', project?.ref ?? '_') |
| 74 | : action.url.includes('[slug]') |
| 75 | ? action.url.replace('[slug]', organization?.slug ?? '_') |
| 76 | : action.url |
| 77 | return ( |
| 78 | <Button key={key} type="default" icon={<ExternalLink strokeWidth={1.5} />} asChild> |
| 79 | <Link href={url} target="_blank" rel="noreferrer"> |
| 80 | {action.label} |
| 81 | </Link> |
| 82 | </Button> |
| 83 | ) |
| 84 | } else if (action.action_type !== undefined) { |
| 85 | return ( |
| 86 | <Button key={key} type="default" onClick={() => onButtonAction(action.action_type)}> |
| 87 | {action.label} |
| 88 | </Button> |
| 89 | ) |
| 90 | } else { |
| 91 | return null |
| 92 | } |
| 93 | })} |
| 94 | {notification.status === 'archived' ? ( |
| 95 | <Button |
| 96 | type="default" |
| 97 | icon={<ArchiveRestoreIcon size={14} strokeWidth={1.5} />} |
| 98 | onClick={() => onUpdateStatus(notification.id, 'seen')} |
| 99 | > |
| 100 | Unarchive |
| 101 | </Button> |
| 102 | ) : ( |
| 103 | <Button |
| 104 | type="default" |
| 105 | icon={<Archive size={14} strokeWidth={1.5} />} |
| 106 | onClick={() => onUpdateStatus(notification.id, 'archived')} |
| 107 | > |
| 108 | Archive |
| 109 | </Button> |
| 110 | )} |
| 111 | </div> |
| 112 | </div> |
| 113 | ) |
| 114 | } |