Support adding comments

This commit is contained in:
Jason Laster 2025-03-20 13:37:22 -07:00
parent fb6afd1926
commit 5fe9f297e7
5 changed files with 43 additions and 30 deletions

View File

@ -177,19 +177,16 @@ export async function deleteProblem(problemId: string): Promise<void | undefined
return undefined;
}
export async function updateProblem(
problemId: string,
problem: BoltProblemInput,
): Promise<void | undefined | BoltProblem> {
export async function updateProblem(problemId: string, problem: BoltProblemInput): Promise<BoltProblem | null> {
if (shouldUseSupabase()) {
return supabaseUpdateProblem(problemId, problem);
await supabaseUpdateProblem(problemId, problem);
}
try {
if (!getNutIsAdmin()) {
toast.error('Admin user required');
return undefined;
return null;
}
const loginKey = Cookies.get(nutLoginKeyCookieName);
@ -200,14 +197,14 @@ export async function updateProblem(
params: { problemId, problem, loginKey },
},
});
return undefined;
} catch (error) {
console.error('Error updating problem', error);
toast.error('Failed to update problem');
}
return undefined;
const updatedProblem = await getProblem(problemId);
return updatedProblem;
}
const nutLoginKeyCookieName = 'nutLoginKey';

View File

@ -159,11 +159,11 @@ export async function supabaseDeleteProblem(problemId: string): Promise<void | u
}
}
export async function supabaseUpdateProblem(problemId: string, problem: BoltProblemInput): Promise<BoltProblem | null> {
export async function supabaseUpdateProblem(problemId: string, problem: BoltProblemInput): Promise<void> {
try {
if (!getNutIsAdmin()) {
toast.error('Admin user required');
return null;
return undefined;
}
// Extract comments to add separately if needed
@ -214,25 +214,17 @@ export async function supabaseUpdateProblem(problemId: string, problem: BoltProb
* Use upsert with onConflict to avoid duplicates.
* This will insert new comments and ignore existing ones based on created_at.
*/
const { error: commentsError, data: commentsData } = await getSupabase()
.from('problem_comments')
.upsert(commentInserts, {
onConflict: 'created_at',
ignoreDuplicates: true,
})
.select();
console.log('commentsData', commentsData);
const { error: commentsError } = await getSupabase().from('problem_comments').upsert(commentInserts, {
onConflict: 'created_at',
ignoreDuplicates: true,
});
if (commentsError) {
throw commentsError;
}
}
// Fetch the updated problem with comments to return to the caller
const updatedProblem = await supabaseGetProblem(problemId);
return updatedProblem;
return undefined;
} catch (error) {
console.error('Error updating problem', error);
toast.error('Failed to update problem');

View File

@ -21,7 +21,11 @@ function Comments({ comments }: { comments: BoltProblemComment[] }) {
return (
<div className="space-y-4 mt-6">
{comments.map((comment, index) => (
<div key={index} className="bg-bolt-elements-background-depth-2 rounded-lg p-4 shadow-sm">
<div
data-testid="problem-comment"
key={index}
className="bg-bolt-elements-background-depth-2 rounded-lg p-4 shadow-sm"
>
<div className="flex items-center justify-between mb-2">
<span className="font-medium text-bolt-text">{comment.username ?? 'Anonymous'}</span>
<span className="text-sm text-bolt-text-secondary">
@ -250,13 +254,10 @@ function ViewProblemPage() {
}
const newProblem = callback(problemData);
setProblemData(newProblem);
console.log('BackendUpdateProblem', problemId, newProblem);
const updatedProblem = await backendUpdateProblem(problemId, newProblem);
// If we got an updated problem back from the backend, use it to update the UI
if (updatedProblem && typeof updatedProblem !== 'undefined') {
if (updatedProblem) {
setProblemData(updatedProblem);
}
},

View File

@ -9,7 +9,7 @@
"scripts": {
"deploy": "vercel deploy --prod",
"build": "npx remix vite:build",
"dev": "pnpm run dev:legacy",
"dev": "node pre-start.cjs && npx remix vite:dev",
"dev:supabase": "node pre-start.cjs && USE_SUPABASE=true npx remix vite:dev",
"dev:legacy": "node pre-start.cjs && USE_SUPABASE=false npx remix vite:dev",
"test": "vitest --run --exclude tests/e2e",

View File

@ -111,3 +111,26 @@ test('Confirm that isAdmin is saved correctly', async ({ page }) => {
await page.reload();
await expect(await page.getByRole('button', { name: 'Set Status' })).toBeVisible();
});
test('Should be able to add a comment to a problem', async ({ page }) => {
await page.goto('/problems?showAll=true');
await page.getByRole('combobox').selectOption('all');
await page.getByRole('link', { name: '[test] playwright' }).first().click();
if (await isSupabaseEnabled(page)) {
await login(page);
} else {
await setLoginKey(page);
}
// Add a comment to the problem
const comment = `test comment ${Date.now().toString()}`;
await page.getByRole('textbox', { name: 'Add a comment...' }).click();
await page.getByRole('textbox', { name: 'Add a comment...' }).fill(comment);
await page.getByRole('button', { name: 'Add Comment' }).click();
await expect(page.locator('[data-testid="problem-comment"]').filter({ hasText: comment })).toBeVisible();
// Reload the page and check that the comment is still visible
await page.reload();
await expect(page.locator('[data-testid="problem-comment"]').filter({ hasText: comment })).toBeVisible();
});