Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/web/components/post/post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { notifyError } from "../core/toast.component";
import ConfirmDeleteDialog from "../dialogs/confirm-delete-dialog.component";
import PostOptions from "./post-options";
import { PostStatusIcon } from "./post-status";
import { createAuditLog } from "../../utils/auditLog";

const ReactionsCounter = ({ aggregate }: { aggregate: IReactions }) => {
return (
Expand Down Expand Up @@ -171,7 +172,7 @@ export function Post({
try {
await supabase.from("posts").delete().eq("id", post.id);

await supabase.from("page_audit_logs").insert({
await createAuditLog(supabase, {
page_id: page.id,
actor_id: user.id,
action: "Deleted Post",
Expand Down
1 change: 1 addition & 0 deletions apps/web/components/roadmap/RoadmapBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export default function RoadmapBoard({
const dragDropHandlers = useRoadmapDragDrop({
itemsByColumn,
setBoardItems,
board,
});

const itemHandlers = useRoadmapItems({
Expand Down
26 changes: 25 additions & 1 deletion apps/web/components/roadmap/hooks/useRoadmapDragDrop.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { Dispatch, SetStateAction, useState } from "react";
import { useUserData } from "../../../utils/useUser";
import { createAuditLog } from "../../../utils/auditLog";
import {
DragOverPosition,
ItemsByColumn,
RoadmapItemWithRelations,
} from "../types";
import { IRoadmapBoard } from "@changes-page/supabase/types/page";

export function useRoadmapDragDrop({
itemsByColumn,
setBoardItems,
board,
}: {
itemsByColumn: ItemsByColumn;
setBoardItems: Dispatch<SetStateAction<RoadmapItemWithRelations[]>>;
board: IRoadmapBoard;
}) {
const { supabase } = useUserData();
const { supabase, user } = useUserData();
const [draggedItem, setDraggedItem] =
useState<RoadmapItemWithRelations | null>(null);
const [dragOverColumn, setDragOverColumn] = useState<string | null>(null);
Expand Down Expand Up @@ -90,6 +94,26 @@ export function useRoadmapDragDrop({
currentDragOverPosition
);
}

// Create audit log for item move
if (user && draggedItem) {
const action = sourceColumnId === targetColumnId ? "Reordered" : "Moved";
const description = sourceColumnId === targetColumnId
? `${action} item within column`
: `${action} item from column to column`;

await createAuditLog(supabase, {
page_id: board.page_id,
actor_id: user.id,
action: `Updated Roadmap Item: ${draggedItem.title}`,
changes: {
action: description,
from_column: sourceColumnId,
to_column: targetColumnId,
item: draggedItem
},
});
}
} catch (error) {
console.error("Error moving item:", error);
alert("Failed to move item");
Expand Down
39 changes: 38 additions & 1 deletion apps/web/components/roadmap/hooks/useRoadmapItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
IRoadmapCategory,
} from "@changes-page/supabase/types/page";
import { useState } from "react";
import { createAuditLog } from "../../../utils/auditLog";
import { useUserData } from "../../../utils/useUser";
import {
FormErrors,
Expand All @@ -20,7 +21,7 @@ export function useRoadmapItems({
categories: IRoadmapCategory[];
itemsByColumn: ItemsByColumn;
}) {
const { supabase } = useUserData();
const { supabase, user } = useUserData();
const [showItemModal, setShowItemModal] = useState(false);
const [selectedColumnId, setSelectedColumnId] = useState<string | null>(null);
const [editingItem, setEditingItem] =
Expand Down Expand Up @@ -66,6 +67,10 @@ export function useRoadmapItems({
if (!confirm("Are you sure you want to delete this item?")) return;

try {
const itemToDelete = Object.values(itemsByColumn)
.flat()
.find((it) => it.id === itemId);

const { error } = await supabase
.from("roadmap_items")
.delete()
Expand All @@ -74,6 +79,15 @@ export function useRoadmapItems({
if (error) throw error;

setBoardItems((prev) => prev.filter((item) => item.id !== itemId));

if (itemToDelete && user) {
await createAuditLog(supabase, {
page_id: board.page_id,
actor_id: user.id,
action: `Deleted Roadmap Item: ${itemToDelete.title}`,
changes: { item_id: itemToDelete.id, item_title: itemToDelete.title },
});
}
} catch (error) {
console.error("Error deleting item:", error);
alert("Failed to delete item");
Expand Down Expand Up @@ -127,6 +141,19 @@ export function useRoadmapItems({
setBoardItems((prev) =>
prev.map((item) => (item.id === editingItem.id ? data : item))
);

// Create audit log for update
if (user) {
await createAuditLog(supabase, {
page_id: board.page_id,
actor_id: user.id,
action: `Updated Roadmap Item: ${data.title}`,
changes: {
old: editingItem,
new: data,
},
});
}
} else {
if (!selectedColumnId) return;

Expand Down Expand Up @@ -162,6 +189,16 @@ export function useRoadmapItems({
if (error) throw error;

setBoardItems((prev) => [...prev, data]);

// Create audit log for creation
if (user) {
await createAuditLog(supabase, {
page_id: board.page_id,
actor_id: user.id,
action: `Created Roadmap Item: ${data.title}`,
changes: { item: data },
});
}
}

setShowItemModal(false);
Expand Down
3 changes: 2 additions & 1 deletion apps/web/pages/api/posts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NewPostSchema } from "../../../data/schema";
import { apiRateLimiter } from "../../../utils/rate-limit";
import { createPost } from "../../../utils/useDatabase";
import { withAuth } from "../../../utils/withAuth";
import { createAuditLog } from "../../../utils/auditLog";

const createNewPost = withAuth(async (req, res, { user, supabase }) => {
if (req.method === "POST") {
Expand Down Expand Up @@ -73,7 +74,7 @@ const createNewPost = withAuth(async (req, res, { user, supabase }) => {

const post = await createPost(postPayload);

await supabase.from("page_audit_logs").insert({
await createAuditLog(supabase, {
page_id,
actor_id: user.id,
action: `Created Post: ${post.title}`,
Expand Down
3 changes: 2 additions & 1 deletion apps/web/pages/pages/[page_id]/[post_id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { NewPostSchema } from "../../../data/schema";
import { withSupabase } from "../../../utils/supabase/withSupabase";
import { createOrRetrievePageSettings } from "../../../utils/useDatabase";
import { useUserData } from "../../../utils/useUser";
import { createAuditLog } from "../../../utils/auditLog";

export const getServerSideProps = withSupabase(async (ctx, { supabase }) => {
const { page_id, post_id } = ctx.params;
Expand Down Expand Up @@ -67,7 +68,7 @@ export default function EditPost({

await supabase.from("posts").update(newPost).match({ id: post_id });

await supabase.from("page_audit_logs").insert({
await createAuditLog(supabase, {
page_id: String(page_id),
actor_id: user.id,
action: `Updated Post: ${newPost.title}`,
Expand Down
111 changes: 108 additions & 3 deletions apps/web/pages/pages/[page_id]/roadmap/[board_id]/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { withSupabase } from "../../../../../utils/supabase/withSupabase";
import { createOrRetrievePageSettings } from "../../../../../utils/useDatabase";
import { getPage } from "../../../../../utils/useSSR";
import { useUserData } from "../../../../../utils/useUser";
import { createAuditLog } from "../../../../../utils/auditLog";

export const getServerSideProps = withSupabase(async (ctx, { supabase }) => {
const { page_id } = ctx.params;
Expand Down Expand Up @@ -235,6 +236,27 @@ export default function BoardSettings({
throw error;
}

// Create audit log for board update
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: `Updated Roadmap Board: ${boardForm.title}`,
changes: {
old: {
title: board.title,
description: board.description,
slug: board.slug,
is_public: board.is_public
},
new: {
title: boardForm.title,
description: boardForm.description,
slug: boardForm.slug,
is_public: boardForm.is_public
}
},
});

// Refresh the page to show updated settings
window.location.reload();
} catch (error) {
Expand Down Expand Up @@ -266,6 +288,14 @@ export default function BoardSettings({
setBoardCategories([...boardCategories, data]);
setNewCategory("");
setNewCategoryColor("blue");

// Create audit log for category creation
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: `Created Roadmap Category: ${data.name}`,
changes: { category: data },
});
} catch (error) {
console.error("Error adding category:", error);
alert("Failed to add category");
Expand All @@ -286,20 +316,38 @@ export default function BoardSettings({

if (error) throw error;

const oldCategory = boardCategories.find(cat => cat.id === categoryId);
const newCategoryData = {
name: categoryToEdit.trim(),
color: categoryColorToEdit,
};

setBoardCategories((prev) =>
prev.map((cat) =>
cat.id === categoryId
? {
...cat,
name: categoryToEdit.trim(),
color: categoryColorToEdit,
...newCategoryData,
}
: cat
)
);
setEditingCategory(null);
setCategoryToEdit("");
setCategoryColorToEdit("blue");

// Create audit log for category update
if (oldCategory) {
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: `Updated Roadmap Category: ${newCategoryData.name}`,
changes: {
old: oldCategory,
new: { ...oldCategory, ...newCategoryData }
},
});
}
} catch (error) {
console.error("Error updating category:", error);
alert("Failed to update category");
Expand Down Expand Up @@ -332,7 +380,18 @@ export default function BoardSettings({

if (error) throw error;

const deletedCategory = boardCategories.find(cat => cat.id === categoryId);
setBoardCategories((prev) => prev.filter((cat) => cat.id !== categoryId));

// Create audit log for category deletion
if (deletedCategory) {
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: `Deleted Roadmap Category: ${deletedCategory.name}`,
changes: { category: deletedCategory },
});
}
} catch (error) {
console.error("Error deleting category:", error);
alert("Failed to delete category");
Expand Down Expand Up @@ -362,6 +421,14 @@ export default function BoardSettings({

setBoardColumns([...boardColumns, data]);
setNewColumn("");

// Create audit log for column creation
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: `Created Roadmap Column: ${data.name}`,
changes: { column: data },
});
} catch (error) {
console.error("Error adding column:", error);
alert("Failed to add column");
Expand All @@ -379,13 +446,29 @@ export default function BoardSettings({

if (error) throw error;

const oldColumn = boardColumns.find(col => col.id === columnId);
const newColumnName = columnToEdit.trim();

setBoardColumns((prev) =>
prev.map((col) =>
col.id === columnId ? { ...col, name: columnToEdit.trim() } : col
col.id === columnId ? { ...col, name: newColumnName } : col
)
);
setEditingColumn(null);
setColumnToEdit("");

// Create audit log for column update
if (oldColumn) {
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: `Updated Roadmap Column: ${newColumnName}`,
changes: {
old: oldColumn,
new: { ...oldColumn, name: newColumnName }
},
});
}
} catch (error) {
console.error("Error updating column:", error);
alert("Failed to update column");
Expand Down Expand Up @@ -420,7 +503,18 @@ export default function BoardSettings({

if (error) throw error;

const deletedColumn = boardColumns.find(col => col.id === columnId);
setBoardColumns((prev) => prev.filter((col) => col.id !== columnId));

// Create audit log for column deletion
if (deletedColumn) {
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: `Deleted Roadmap Column: ${deletedColumn.name}`,
changes: { column: deletedColumn },
});
}
} catch (error) {
console.error("Error deleting column:", error);
alert("Failed to delete column");
Expand Down Expand Up @@ -471,6 +565,17 @@ export default function BoardSettings({

await Promise.all(updatePromises);

// Create audit log for column reordering
await createAuditLog(supabase, {
page_id: page_id,
actor_id: user.id,
action: "Reordered Roadmap Columns",
changes: {
old_order: boardColumns.map(col => ({ id: col.id, name: col.name, position: col.position })),
new_order: newColumns.map((col, index) => ({ id: col.id, name: col.name, position: index + 1 }))
},
});

// Update local state
setBoardColumns(
newColumns.map((column, index) => ({
Expand Down
Loading