From dbc09bd7af8ac6a7f3f21cb4d0d1522a0b5b69fd Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 1 Feb 2024 15:58:28 +0800 Subject: [PATCH] :sparkles: Notifications --- pkg/models/notifications.go | 1 + pkg/server/accounts_api.go | 1 - pkg/server/notifications_api.go | 59 +++++++++++++++++++++++++++ pkg/server/startup.go | 3 ++ pkg/view/src/pages/dashboard.tsx | 70 ++++++++++++++++++++++++++++---- 5 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 pkg/server/notifications_api.go diff --git a/pkg/models/notifications.go b/pkg/models/notifications.go index 9eed3ad..3929d69 100644 --- a/pkg/models/notifications.go +++ b/pkg/models/notifications.go @@ -9,5 +9,6 @@ type Notification struct { Content string `json:"content"` IsImportant bool `json:"is_important"` ReadAt *time.Time `json:"read_at"` + SenderID *uint `json:"sender_id"` RecipientID uint `json:"recipient_id"` } diff --git a/pkg/server/accounts_api.go b/pkg/server/accounts_api.go index c405d2d..db44110 100644 --- a/pkg/server/accounts_api.go +++ b/pkg/server/accounts_api.go @@ -20,7 +20,6 @@ func getUserinfo(c *fiber.Ctx) error { Where(&models.Account{BaseModel: models.BaseModel{ID: user.ID}}). Preload("Profile"). Preload("Contacts"). - Preload("Factors"). Preload("Notifications", "read_at IS NULL"). First(&data).Error; err != nil { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) diff --git a/pkg/server/notifications_api.go b/pkg/server/notifications_api.go new file mode 100644 index 0000000..669081f --- /dev/null +++ b/pkg/server/notifications_api.go @@ -0,0 +1,59 @@ +package server + +import ( + "code.smartsheep.studio/hydrogen/passport/pkg/database" + "code.smartsheep.studio/hydrogen/passport/pkg/models" + "github.com/gofiber/fiber/v2" + "github.com/samber/lo" + "time" +) + +func getNotifications(c *fiber.Ctx) error { + user := c.Locals("principal").(models.Account) + take := c.QueryInt("take", 0) + offset := c.QueryInt("offset", 0) + + var count int64 + var notifications []models.Notification + if err := database.C. + Where(&models.Notification{RecipientID: user.ID}). + Model(&models.Notification{}). + Count(&count).Error; err != nil { + return fiber.NewError(fiber.StatusInternalServerError, err.Error()) + } + + if err := database.C. + Where(&models.Notification{RecipientID: user.ID}). + Limit(take). + Offset(offset). + Order("read_at desc"). + Find(¬ifications).Error; err != nil { + return fiber.NewError(fiber.StatusInternalServerError, err.Error()) + } + + return c.JSON(fiber.Map{ + "count": count, + "data": notifications, + }) +} + +func markNotificationRead(c *fiber.Ctx) error { + user := c.Locals("principal").(models.Account) + id, _ := c.ParamsInt("notificationId", 0) + + var data models.Notification + if err := database.C.Where(&models.Notification{ + BaseModel: models.BaseModel{ID: uint(id)}, + RecipientID: user.ID, + }).First(&data).Error; err != nil { + return fiber.NewError(fiber.StatusNotFound, err.Error()) + } + + data.ReadAt = lo.ToPtr(time.Now()) + + if err := database.C.Save(&data).Error; err != nil { + return fiber.NewError(fiber.StatusInternalServerError, err.Error()) + } else { + return c.SendStatus(fiber.StatusOK) + } +} diff --git a/pkg/server/startup.go b/pkg/server/startup.go index 8e37bca..948117e 100644 --- a/pkg/server/startup.go +++ b/pkg/server/startup.go @@ -60,6 +60,9 @@ func NewServer() { api.Get("/avatar/:avatarId", getAvatar) api.Put("/avatar", auth, setAvatar) + api.Get("/notifications", auth, getNotifications) + api.Put("/notifications/:notificationId/read", auth, markNotificationRead) + api.Get("/users/me", auth, getUserinfo) api.Put("/users/me", auth, editUserinfo) api.Get("/users/me/events", auth, getEvents) diff --git a/pkg/view/src/pages/dashboard.tsx b/pkg/view/src/pages/dashboard.tsx index 1f68a1f..de7cab7 100644 --- a/pkg/view/src/pages/dashboard.tsx +++ b/pkg/view/src/pages/dashboard.tsx @@ -1,9 +1,11 @@ -import { useUserinfo } from "../stores/userinfo.tsx"; -import { Show } from "solid-js"; +import { getAtk, readProfiles, useUserinfo } from "../stores/userinfo.tsx"; +import { createSignal, For, Show } from "solid-js"; export default function DashboardPage() { const userinfo = useUserinfo(); + const [error, setError] = createSignal(null); + function getGreeting() { const currentHour = new Date().getHours(); @@ -16,6 +18,19 @@ export default function DashboardPage() { } } + async function readNotification(item: any) { + const res = await fetch(`/api/notifications/${item.id}/read`, { + method: "PUT", + headers: { Authorization: `Bearer ${getAtk()}` } + }); + if (res.status !== 200) { + setError(await res.text()); + } else { + await readProfiles(); + setError(null); + } + } + return (
@@ -37,17 +52,54 @@ export default function DashboardPage() {
+ + +
-

Recommendations

-
    -
  1. 1. Turn on the notification of us.
  2. -
  3. 2. Download passport mobile application.
  4. -
  5. 3. Add more factor to keep your account in safe.
  6. -
  7. 4. Subscribe to Project Hydrogen to get following updates.
  8. -
+

Notifications

+
+ + + + + + + +
You're done! There are no notifications unread for you.
+
+ 0}> + + + + {item => + + + + } + + +
+

{item.subject}

+

{item.content}

+ +
+
+