my-first-valvotes.ts14 matches
7import { requireAuth } from "./auth.ts";
8import { isPollActive } from "../../shared/utils.ts";
9import type { VoteRequest, ApiResponse, User } from "../../shared/types.ts";
1011const votes = new Hono();
19// Validate input
20if (!body.poll_id || !body.option_id) {
21return c.json<ApiResponse>({
22success: false,
23error: "Poll ID and option ID are required"
2930if (isNaN(pollId) || isNaN(optionId)) {
31return c.json<ApiResponse>({
32success: false,
33error: "Invalid poll ID or option ID"
38const poll = await getPollById(pollId, user.id);
39if (!poll) {
40return c.json<ApiResponse>({
41success: false,
42error: "Poll not found"
46// Check if poll is active
47if (!isPollActive(poll)) {
48return c.json<ApiResponse>({
49success: false,
50error: "Poll is not currently active"
54// Check if user has already voted
55if (poll.user_has_voted) {
56return c.json<ApiResponse>({
57success: false,
58error: "You have already voted on this poll"
63const validOption = poll.options.find(option => option.id === optionId);
64if (!validOption) {
65return c.json<ApiResponse>({
66success: false,
67error: "Invalid option for this poll"
73
74if (!vote) {
75return c.json<ApiResponse>({
76success: false,
77error: "Failed to cast vote"
79}
8081return c.json<ApiResponse>({
82success: true,
83data: vote
86} catch (error) {
87console.error("Cast vote error:", error);
88return c.json<ApiResponse>({
89success: false,
90error: "Internal server error"
100101if (isNaN(pollId)) {
102return c.json<ApiResponse>({
103success: false,
104error: "Invalid poll ID"
109const poll = await getPollById(pollId);
110if (!poll) {
111return c.json<ApiResponse>({
112success: false,
113error: "Poll not found"
117const vote = await getUserVote(pollId, user.id);
118119return c.json<ApiResponse>({
120success: true,
121data: vote
124} catch (error) {
125console.error("Get user vote error:", error);
126return c.json<ApiResponse>({
127success: false,
128error: "Internal server error"
my-first-valpolls.ts33 matches
11import { requireAuth } from "./auth.ts";
12import { sanitizeInput, isPollActive } from "../../shared/utils.ts";
13import type { CreatePollRequest, ApiResponse, User } from "../../shared/types.ts";
1415const polls = new Hono();
28const allPolls = await getAllPolls(userId);
29
30return c.json<ApiResponse>({
31success: true,
32data: allPolls
35} catch (error) {
36console.error("Get polls error:", error);
37return c.json<ApiResponse>({
38success: false,
39error: "Internal server error"
48
49if (isNaN(pollId)) {
50return c.json<ApiResponse>({
51success: false,
52error: "Invalid poll ID"
65
66if (!poll) {
67return c.json<ApiResponse>({
68success: false,
69error: "Poll not found"
71}
7273return c.json<ApiResponse>({
74success: true,
75data: poll
78} catch (error) {
79console.error("Get poll error:", error);
80return c.json<ApiResponse>({
81success: false,
82error: "Internal server error"
93// Validate input
94if (!body.title || !body.description || !body.options || !body.start_date || !body.end_date) {
95return c.json<ApiResponse>({
96success: false,
97error: "Title, description, options, start_date, and end_date are required"
100101if (!Array.isArray(body.options) || body.options.length < 2) {
102return c.json<ApiResponse>({
103success: false,
104error: "At least 2 options are required"
107108if (body.options.length > 10) {
109return c.json<ApiResponse>({
110success: false,
111error: "Maximum 10 options allowed"
119120if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
121return c.json<ApiResponse>({
122success: false,
123error: "Invalid date format"
126127if (endDate <= startDate) {
128return c.json<ApiResponse>({
129success: false,
130error: "End date must be after start date"
133134if (endDate <= now) {
135return c.json<ApiResponse>({
136success: false,
137error: "End date must be in the future"
149150if (pollData.options.length < 2) {
151return c.json<ApiResponse>({
152success: false,
153error: "At least 2 valid options are required after sanitization"
157const poll = await createPoll(pollData, user.id);
158159return c.json<ApiResponse>({
160success: true,
161data: poll
164} catch (error) {
165console.error("Create poll error:", error);
166return c.json<ApiResponse>({
167success: false,
168error: "Internal server error"
178
179if (isNaN(pollId)) {
180return c.json<ApiResponse>({
181success: false,
182error: "Invalid poll ID"
186const existingPoll = await getPollById(pollId);
187if (!existingPoll) {
188return c.json<ApiResponse>({
189success: false,
190error: "Poll not found"
194// Check permissions
195if (existingPoll.creator_id !== user.id && !user.is_admin) {
196return c.json<ApiResponse>({
197success: false,
198error: "Permission denied"
216const startDate = new Date(body.start_date);
217if (isNaN(startDate.getTime())) {
218return c.json<ApiResponse>({
219success: false,
220error: "Invalid start date format"
226const endDate = new Date(body.end_date);
227if (isNaN(endDate.getTime())) {
228return c.json<ApiResponse>({
229success: false,
230error: "Invalid end date format"
236const updatedPoll = await updatePoll(pollId, updates);
237238return c.json<ApiResponse>({
239success: true,
240data: updatedPoll
243} catch (error) {
244console.error("Update poll error:", error);
245return c.json<ApiResponse>({
246success: false,
247error: "Internal server error"
257
258if (isNaN(pollId)) {
259return c.json<ApiResponse>({
260success: false,
261error: "Invalid poll ID"
265const existingPoll = await getPollById(pollId);
266if (!existingPoll) {
267return c.json<ApiResponse>({
268success: false,
269error: "Poll not found"
273// Check permissions
274if (existingPoll.creator_id !== user.id && !user.is_admin) {
275return c.json<ApiResponse>({
276success: false,
277error: "Permission denied"
282
283if (!deleted) {
284return c.json<ApiResponse>({
285success: false,
286error: "Failed to delete poll"
288}
289290return c.json<ApiResponse>({
291success: true
292});
294} catch (error) {
295console.error("Delete poll error:", error);
296return c.json<ApiResponse>({
297success: false,
298error: "Internal server error"
307
308if (isNaN(pollId)) {
309return c.json<ApiResponse>({
310success: false,
311error: "Invalid poll ID"
316
317if (!poll) {
318return c.json<ApiResponse>({
319success: false,
320error: "Poll not found"
337};
338339return c.json<ApiResponse>({
340success: true,
341data: results
344} catch (error) {
345console.error("Get poll results error:", error);
346return c.json<ApiResponse>({
347success: false,
348error: "Internal server error"
16await runMigrations();
1718// API routes
19app.route("/api/jobs", jobsRouter);
20app.route("/api/chat", chatRouter);
2122// Serve static files
DERICKChatroom.tsx2 matches
33// Setup SSE connection for real-time messages
34useEffect(() => {
35const eventSource = new EventSource('/api/chat/stream');
36eventSourceRef.current = eventSource;
3783};
8485const response = await fetch('/api/chat/messages', {
86method: 'POST',
87headers: {
my-first-valauth.ts21 matches
11} from "../database/queries.ts";
12import { isValidEmail, isValidUsername, isValidPassword, sanitizeInput } from "../../shared/utils.ts";
13import type { LoginRequest, RegisterRequest, ApiResponse } from "../../shared/types.ts";
1415const auth = new Hono();
28// Validate input
29if (!username || !email || !password) {
30return c.json<ApiResponse>({
31success: false,
32error: "Username, email, and password are required"
3839if (!isValidUsername(cleanUsername)) {
40return c.json<ApiResponse>({
41success: false,
42error: "Username must be 3-20 characters, alphanumeric and underscores only"
4546if (!isValidEmail(cleanEmail)) {
47return c.json<ApiResponse>({
48success: false,
49error: "Invalid email format"
5253if (!isValidPassword(password)) {
54return c.json<ApiResponse>({
55success: false,
56error: "Password must be at least 6 characters"
61const existingUser = await getUserByUsername(cleanUsername) || await getUserByEmail(cleanEmail);
62if (existingUser) {
63return c.json<ApiResponse>({
64success: false,
65error: "Username or email already exists"
89// Return user without password hash
90const { password_hash, ...userResponse } = user;
91return c.json<ApiResponse>({
92success: true,
93data: userResponse
96} catch (error) {
97console.error("Registration error:", error);
98return c.json<ApiResponse>({
99success: false,
100error: "Internal server error"
110111if (!username || !password) {
112return c.json<ApiResponse>({
113success: false,
114error: "Username and password are required"
119const user = await getUserByUsername(sanitizeInput(username));
120if (!user) {
121return c.json<ApiResponse>({
122success: false,
123error: "Invalid username or password"
128const isValidPassword = await bcrypt.compare(password, user.password_hash);
129if (!isValidPassword) {
130return c.json<ApiResponse>({
131success: false,
132error: "Invalid username or password"
150// Return user without password hash
151const { password_hash, ...userResponse } = user;
152return c.json<ApiResponse>({
153success: true,
154data: userResponse
157} catch (error) {
158console.error("Login error:", error);
159return c.json<ApiResponse>({
160success: false,
161error: "Internal server error"
176deleteCookie(c, "session_id", { path: "/" });
177178return c.json<ApiResponse>({ success: true });
179180} catch (error) {
181console.error("Logout error:", error);
182return c.json<ApiResponse>({
183success: false,
184error: "Internal server error"
193
194if (!sessionId) {
195return c.json<ApiResponse>({
196success: false,
197error: "Not authenticated"
201const user = await getSessionUser(sessionId);
202if (!user) {
203return c.json<ApiResponse>({
204success: false,
205error: "Invalid session"
209// Return user without password hash
210const { password_hash, ...userResponse } = user;
211return c.json<ApiResponse>({
212success: true,
213data: userResponse
216} catch (error) {
217console.error("Get user error:", error);
218return c.json<ApiResponse>({
219success: false,
220error: "Internal server error"
228
229if (!sessionId) {
230return c.json<ApiResponse>({
231success: false,
232error: "Authentication required"
236const user = await getSessionUser(sessionId);
237if (!user) {
238return c.json<ApiResponse>({
239success: false,
240error: "Invalid session"
DERICKJobForm.tsx1 match
33};
3435const response = await fetch('/api/jobs', {
36method: 'POST',
37headers: {
untitled-7041index.ts2 matches
15await createTodosTable();
1617// API routes
18app.route("/api/todos", todosRouter);
1920// Serve static files
untitled-1496index.ts5 matches
16await runMigrations();
1718// API routes
19app.route('/api/auth', authRoutes);
20app.route('/api/polls', pollRoutes);
21app.route('/api/votes', voteRoutes);
2223// Health check endpoint
24app.get('/api/health', (c) => {
25return c.json({ status: 'ok', timestamp: new Date().toISOString() });
26});
untitled-1496CreatePoll.tsx1 match
78};
7980const response = await fetch('/api/polls', {
81method: 'POST',
82headers: {
untitled-7041App.tsx10 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState, useEffect } from "https://esm.sh/react@18.2.0?deps=react@18.2.0,react-dom@18.2.0";
3import type { Todo, CreateTodoRequest, UpdateTodoRequest, ApiResponse } from "../../shared/types.ts";
4import TodoForm from "./TodoForm.tsx";
5import TodoItem from "./TodoItem.tsx";
13const [error, setError] = useState<string | null>(null);
1415// Fetch todos from API
16const fetchTodos = async () => {
17try {
18setLoading(true);
19setError(null);
20const response = await fetch("/api/todos");
21const result: ApiResponse<Todo[]> = await response.json();
22
23if (result.success && result.data) {
37try {
38setError(null);
39const response = await fetch("/api/todos", {
40method: "POST",
41headers: {
45});
46
47const result: ApiResponse<Todo> = await response.json();
48
49if (result.success && result.data) {
61try {
62setError(null);
63const response = await fetch(`/api/todos/${id}`, {
64method: "PUT",
65headers: {
69});
70
71const result: ApiResponse<Todo> = await response.json();
72
73if (result.success && result.data) {
87try {
88setError(null);
89const response = await fetch(`/api/todos/${id}`, {
90method: "DELETE",
91});
92
93const result: ApiResponse<{ deleted: boolean }> = await response.json();
94
95if (result.success) {