mirror of
https://github.com/spliit-app/spliit.git
synced 2026-02-26 01:16:12 +01:00
Add basic activity log (#141)
* Add basic activity log * Add database migration * Fix layout * Fix types --------- Co-authored-by: Sebastien Castiel <sebastien@castiel.me>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { ExpenseFormValues, GroupFormValues } from '@/lib/schemas'
|
||||
import { Expense } from '@prisma/client'
|
||||
import { ActivityType, Expense } from '@prisma/client'
|
||||
import { nanoid } from 'nanoid'
|
||||
|
||||
export function randomId() {
|
||||
@@ -29,6 +29,7 @@ export async function createGroup(groupFormValues: GroupFormValues) {
|
||||
export async function createExpense(
|
||||
expenseFormValues: ExpenseFormValues,
|
||||
groupId: string,
|
||||
participantId?: string,
|
||||
): Promise<Expense> {
|
||||
const group = await getGroup(groupId)
|
||||
if (!group) throw new Error(`Invalid group ID: ${groupId}`)
|
||||
@@ -41,9 +42,16 @@ export async function createExpense(
|
||||
throw new Error(`Invalid participant ID: ${participant}`)
|
||||
}
|
||||
|
||||
const expenseId = randomId()
|
||||
await logActivity(groupId, ActivityType.CREATE_EXPENSE, {
|
||||
participantId,
|
||||
expenseId,
|
||||
data: expenseFormValues.title,
|
||||
})
|
||||
|
||||
return prisma.expense.create({
|
||||
data: {
|
||||
id: randomId(),
|
||||
id: expenseId,
|
||||
groupId,
|
||||
expenseDate: expenseFormValues.expenseDate,
|
||||
categoryId: expenseFormValues.category,
|
||||
@@ -75,7 +83,18 @@ export async function createExpense(
|
||||
})
|
||||
}
|
||||
|
||||
export async function deleteExpense(expenseId: string) {
|
||||
export async function deleteExpense(
|
||||
groupId: string,
|
||||
expenseId: string,
|
||||
participantId?: string,
|
||||
) {
|
||||
const existingExpense = await getExpense(groupId, expenseId)
|
||||
await logActivity(groupId, ActivityType.DELETE_EXPENSE, {
|
||||
participantId,
|
||||
expenseId,
|
||||
data: existingExpense?.title,
|
||||
})
|
||||
|
||||
await prisma.expense.delete({
|
||||
where: { id: expenseId },
|
||||
include: { paidFor: true, paidBy: true },
|
||||
@@ -110,6 +129,7 @@ export async function updateExpense(
|
||||
groupId: string,
|
||||
expenseId: string,
|
||||
expenseFormValues: ExpenseFormValues,
|
||||
participantId?: string,
|
||||
) {
|
||||
const group = await getGroup(groupId)
|
||||
if (!group) throw new Error(`Invalid group ID: ${groupId}`)
|
||||
@@ -125,6 +145,12 @@ export async function updateExpense(
|
||||
throw new Error(`Invalid participant ID: ${participant}`)
|
||||
}
|
||||
|
||||
await logActivity(groupId, ActivityType.UPDATE_EXPENSE, {
|
||||
participantId,
|
||||
expenseId,
|
||||
data: expenseFormValues.title,
|
||||
})
|
||||
|
||||
return prisma.expense.update({
|
||||
where: { id: expenseId },
|
||||
data: {
|
||||
@@ -189,10 +215,13 @@ export async function updateExpense(
|
||||
export async function updateGroup(
|
||||
groupId: string,
|
||||
groupFormValues: GroupFormValues,
|
||||
participantId?: string,
|
||||
) {
|
||||
const existingGroup = await getGroup(groupId)
|
||||
if (!existingGroup) throw new Error('Invalid group ID')
|
||||
|
||||
await logActivity(groupId, ActivityType.UPDATE_GROUP, { participantId })
|
||||
|
||||
return prisma.group.update({
|
||||
where: { id: groupId },
|
||||
data: {
|
||||
@@ -273,3 +302,25 @@ export async function getExpense(groupId: string, expenseId: string) {
|
||||
include: { paidBy: true, paidFor: true, category: true, documents: true },
|
||||
})
|
||||
}
|
||||
|
||||
export async function getActivities(groupId: string) {
|
||||
return prisma.activity.findMany({
|
||||
where: { groupId },
|
||||
orderBy: [{ time: 'desc' }],
|
||||
})
|
||||
}
|
||||
|
||||
export async function logActivity(
|
||||
groupId: string,
|
||||
activityType: ActivityType,
|
||||
extra?: { participantId?: string; expenseId?: string; data?: string },
|
||||
) {
|
||||
return prisma.activity.create({
|
||||
data: {
|
||||
id: randomId(),
|
||||
groupId,
|
||||
activityType,
|
||||
...extra,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,9 +10,15 @@ export function delay(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
export function formatExpenseDate(date: Date) {
|
||||
return date.toLocaleDateString('en-US', {
|
||||
dateStyle: 'medium',
|
||||
export type DateTimeStyle = NonNullable<
|
||||
ConstructorParameters<typeof Intl.DateTimeFormat>[1]
|
||||
>['dateStyle']
|
||||
export function formatDate(
|
||||
date: Date,
|
||||
options: { dateStyle?: DateTimeStyle; timeStyle?: DateTimeStyle } = {},
|
||||
) {
|
||||
return date.toLocaleString('en-GB', {
|
||||
...options,
|
||||
timeZone: 'UTC',
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user