feat: shop buy, forum replies, tickets, messages, sessions, and UX hardening
Deploy / release (push) Skipped
Deploy / deploy (push) Failing after 4m23s

Complete remaining product gaps: credit-based shop purchases, guild thread replies, help ticket detail/reply/close, offline message compose, sign-out-everywhere via JWT version, ads delete confirm, soft-fail feedback, rate limits, loading states, and single auth() in site layout.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-21 21:21:02 +02:00
1 parent ed7db6e048
commit 803e8f36c1
47 files changed
+2793 -358

No files matched your search

+8 -2
View File
@@ -16,7 +16,7 @@ import { sanitize } from "@/lib/sanitize";
export const revalidate = 60;
type SearchParams = Promise<{ comment?: string; error?: string }>;
type SearchParams = Promise<{ comment?: string; reaction?: string; error?: string }>;
function feedbackStyle(tone: "success" | "error"): CSSProperties {
const accent =
@@ -87,7 +87,7 @@ export default async function ArticlePage({
searchParams: SearchParams;
}) {
const { slug } = await params;
const { comment, error } = await searchParams;
const { comment, reaction, error } = await searchParams;
const t = await getTranslations("pages.article");
const article = await cacheQuery(
@@ -189,6 +189,11 @@ export default async function ArticlePage({
{t("success.posted")}
</div>
) : null}
{reaction === "1" ? (
<div role="status" style={feedbackStyle("success")}>
{t("success.reaction")}
</div>
) : null}
{errorMessage ? (
<div role="alert" style={feedbackStyle("error")}>
{errorMessage}
@@ -240,6 +245,7 @@ export default async function ArticlePage({
name="articleId"
value={String(articleId)}
/>
<input type="hidden" name="slug" value={article.slug} />
<input type="hidden" name="reaction" value={r.key} />
<button
type="submit"