mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
support comments
This commit is contained in:
parent
dbd3ecf48e
commit
fb6afd1926
@ -177,7 +177,10 @@ export async function deleteProblem(problemId: string): Promise<void | undefined
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function updateProblem(problemId: string, problem: BoltProblemInput): Promise<void | undefined> {
|
||||
export async function updateProblem(
|
||||
problemId: string,
|
||||
problem: BoltProblemInput,
|
||||
): Promise<void | undefined | BoltProblem> {
|
||||
if (shouldUseSupabase()) {
|
||||
return supabaseUpdateProblem(problemId, problem);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ export async function supabaseGetProblem(problemId: string): Promise<BoltProblem
|
||||
username,
|
||||
comments: data.problem_comments.map((comment: any) => ({
|
||||
id: comment.id,
|
||||
createdAt: comment.created_at,
|
||||
timestamp: comment.created_at,
|
||||
problemId: comment.problem_id,
|
||||
content: comment.content,
|
||||
username: comment.username,
|
||||
@ -159,11 +159,11 @@ export async function supabaseDeleteProblem(problemId: string): Promise<void | u
|
||||
}
|
||||
}
|
||||
|
||||
export async function supabaseUpdateProblem(problemId: string, problem: BoltProblemInput): Promise<void | undefined> {
|
||||
export async function supabaseUpdateProblem(problemId: string, problem: BoltProblemInput): Promise<BoltProblem | null> {
|
||||
try {
|
||||
if (!getNutIsAdmin()) {
|
||||
toast.error('Admin user required');
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Extract comments to add separately if needed
|
||||
@ -192,37 +192,53 @@ export async function supabaseUpdateProblem(problemId: string, problem: BoltProb
|
||||
* Create a unique identifier for each comment based on content and timestamp.
|
||||
* This allows us to use upsert with onConflict to avoid duplicates.
|
||||
*/
|
||||
const commentInserts = comments.map((comment) => ({
|
||||
problem_id: problemId,
|
||||
content: comment.content,
|
||||
username: comment.username || getUsername() || 'Anonymous',
|
||||
const commentInserts = comments.map((comment) => {
|
||||
// Ensure timestamp is a valid number
|
||||
const timestamp =
|
||||
typeof comment.timestamp === 'number' && !isNaN(comment.timestamp) ? comment.timestamp : Date.now();
|
||||
|
||||
/**
|
||||
* Use timestamp as a unique identifier for the comment.
|
||||
* This assumes that comments with the same timestamp are the same comment.
|
||||
*/
|
||||
created_at: new Date(comment.timestamp).toISOString(),
|
||||
}));
|
||||
return {
|
||||
problem_id: problemId,
|
||||
content: comment.content,
|
||||
username: comment.username || getUsername() || 'Anonymous',
|
||||
|
||||
/**
|
||||
* Use timestamp as a unique identifier for the comment.
|
||||
* This assumes that comments with the same timestamp are the same comment.
|
||||
*/
|
||||
created_at: new Date(timestamp).toISOString(),
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Use upsert with onConflict to avoid duplicates.
|
||||
* This will insert new comments and ignore existing ones based on created_at.
|
||||
*/
|
||||
const { error: commentsError } = await getSupabase().from('problem_comments').upsert(commentInserts, {
|
||||
onConflict: 'created_at',
|
||||
ignoreDuplicates: true,
|
||||
});
|
||||
const { error: commentsError, data: commentsData } = await getSupabase()
|
||||
.from('problem_comments')
|
||||
.upsert(commentInserts, {
|
||||
onConflict: 'created_at',
|
||||
ignoreDuplicates: true,
|
||||
})
|
||||
.select();
|
||||
|
||||
console.log('commentsData', commentsData);
|
||||
|
||||
if (commentsError) {
|
||||
throw commentsError;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch the updated problem with comments to return to the caller
|
||||
const updatedProblem = await supabaseGetProblem(problemId);
|
||||
|
||||
return updatedProblem;
|
||||
} catch (error) {
|
||||
console.error('Error updating problem', error);
|
||||
toast.error('Failed to update problem');
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export async function supabaseSubmitFeedback(feedback: any) {
|
||||
|
@ -24,7 +24,12 @@ function Comments({ comments }: { comments: BoltProblemComment[] }) {
|
||||
<div 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">{new Date(comment.timestamp).toLocaleString()}</span>
|
||||
<span className="text-sm text-bolt-text-secondary">
|
||||
{(() => {
|
||||
const date = new Date(comment.timestamp);
|
||||
return date && !isNaN(date.getTime()) ? date.toLocaleString() : 'Unknown date';
|
||||
})()}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-bolt-text whitespace-pre-wrap">{comment.content}</div>
|
||||
</div>
|
||||
@ -247,7 +252,13 @@ function ViewProblemPage() {
|
||||
const newProblem = callback(problemData);
|
||||
setProblemData(newProblem);
|
||||
console.log('BackendUpdateProblem', problemId, newProblem);
|
||||
await 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') {
|
||||
setProblemData(updatedProblem);
|
||||
}
|
||||
},
|
||||
[problemData],
|
||||
);
|
||||
|
@ -9,9 +9,9 @@
|
||||
"scripts": {
|
||||
"deploy": "vercel deploy --prod",
|
||||
"build": "npx remix vite:build",
|
||||
"dev": "node pre-start.cjs && npx remix vite:dev",
|
||||
"dev:supabase": "USE_SUPABASE=true node pre-start.cjs && npx remix vite:dev",
|
||||
"dev:legacy": "USE_SUPABASE=false node pre-start.cjs && npx remix vite:dev",
|
||||
"dev": "pnpm run dev:legacy",
|
||||
"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",
|
||||
"test:watch": "vitest",
|
||||
"test:e2e": "playwright test",
|
||||
|
Loading…
Reference in New Issue
Block a user