feat: migrate site to TanStack Start
This commit is contained in:
parent
056daa6460
commit
1bf7b32040
33 changed files with 8684 additions and 1106 deletions
101
src/lib/qa-server.ts
Normal file
101
src/lib/qa-server.ts
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import { createServerFn } from "@tanstack/react-start";
|
||||
|
||||
export interface Question {
|
||||
id: number;
|
||||
question: string;
|
||||
answer: string;
|
||||
created_at: string;
|
||||
answered_at: string;
|
||||
}
|
||||
|
||||
export interface QuestionStats {
|
||||
asked: number;
|
||||
answered: number;
|
||||
}
|
||||
|
||||
const DEV_QUESTIONS: Question[] = [
|
||||
{
|
||||
id: 1,
|
||||
question: "What is a fact about octopuses?",
|
||||
answer: "An octopus has three hearts and blue blood.",
|
||||
created_at: "2026-03-23T18:10:00.000Z",
|
||||
answered_at: "2026-03-23T19:00:00.000Z",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
question: "What is a fact about axolotls?",
|
||||
answer:
|
||||
"An axolotl can regrow limbs, parts of its heart, and even parts of its brain.",
|
||||
created_at: "2026-03-24T02:15:00.000Z",
|
||||
answered_at: "2026-03-24T05:45:00.000Z",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
question: "What is a fact about crows?",
|
||||
answer: "Crows can recognize human faces and remember them for years.",
|
||||
created_at: "2026-03-25T08:30:00.000Z",
|
||||
answered_at: "2026-03-25T09:05:00.000Z",
|
||||
},
|
||||
];
|
||||
|
||||
const DEV_QUESTION_STATS: QuestionStats = {
|
||||
asked: 16,
|
||||
answered: DEV_QUESTIONS.length,
|
||||
};
|
||||
|
||||
function apiUrl(path: string) {
|
||||
const base = process.env.QA_API_BASE_URL ?? "http://127.0.0.1:3003";
|
||||
return new URL(path, base).toString();
|
||||
}
|
||||
|
||||
export const getQuestions = createServerFn({ method: "GET" }).handler(
|
||||
async (): Promise<Question[]> => {
|
||||
if (process.env.NODE_ENV === "development") return DEV_QUESTIONS;
|
||||
|
||||
try {
|
||||
const res = await fetch(apiUrl("/api/questions"));
|
||||
if (!res.ok) throw new Error("Failed to fetch questions");
|
||||
return (await res.json()) as Question[];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export const getQuestionStats = createServerFn({ method: "GET" }).handler(
|
||||
async (): Promise<QuestionStats> => {
|
||||
if (process.env.NODE_ENV === "development") return DEV_QUESTION_STATS;
|
||||
|
||||
try {
|
||||
const res = await fetch(apiUrl("/api/questions/stats"));
|
||||
if (!res.ok) throw new Error("Failed to fetch question stats");
|
||||
return (await res.json()) as QuestionStats;
|
||||
} catch {
|
||||
const questions = await getQuestions.__executeServer({
|
||||
method: "GET",
|
||||
data: undefined,
|
||||
});
|
||||
return {
|
||||
asked: (questions as Question[]).length,
|
||||
answered: (questions as Question[]).length,
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export const submitQuestion = createServerFn({ method: "POST" })
|
||||
.inputValidator((question: string) => question)
|
||||
.handler(async ({ data: question }): Promise<void> => {
|
||||
const res = await fetch(apiUrl("/api/questions"), {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ question }),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
if (res.status === 429) {
|
||||
throw new Error("Too many questions. Please try again later.");
|
||||
}
|
||||
throw new Error("Failed to submit question");
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue