27});
2829// API endpoint for contact form submissions (example)
30app.post("/api/contact", async c => {
31try {
32const formData = await c.req.json();
51});
5253// API endpoint for get involved form submissions (example)
54app.post("/api/get-involved", async c => {
55try {
56const formData = await c.req.json();
7172// Health check endpoint
73app.get("/api/health", c => {
74return c.json({ status: "ok", timestamp: new Date().toISOString() });
75});
untitled-3016index.ts3 matches
15await runMigrations();
1617// API routes
18app.route("/api/jobs", jobsRouter);
19app.route("/api/chat", chatRouter);
2021// Serve static files
untitled-3016ChatRoom.tsx5 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState, useEffect, useRef } from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { ChatMessage, ApiResponse } from "../../shared/types.ts";
45export default function ChatRoom() {
19try {
20setLoading(true);
21const response = await fetch('/api/chat/messages');
22const result: ApiResponse<ChatMessage[]> = await response.json();
23
24if (result.success && result.data) {
4647try {
48const response = await fetch('/api/chat/messages', {
49method: 'POST',
50headers: {
57});
5859const result: ApiResponse<ChatMessage> = await response.json();
6061if (result.success && result.data) {
untitled-3016JobForm.tsx3 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState } from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { Job, ApiResponse } from "../../shared/types.ts";
45interface JobFormProps {
2526try {
27const response = await fetch('/api/jobs', {
28method: 'POST',
29headers: {
33});
3435const result: ApiResponse<Job> = await response.json();
3637if (result.success && result.data) {
untitled-3016JobBoard.tsx5 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";
3import type { Job, ApiResponse } from "../../shared/types.ts";
4import JobForm from "./JobForm.tsx";
513try {
14setLoading(true);
15const response = await fetch('/api/jobs');
16const result: ApiResponse<Job[]> = await response.json();
17
18if (result.success && result.data) {
4041try {
42const response = await fetch(`/api/jobs/${jobId}`, {
43method: 'DELETE'
44});
45const result: ApiResponse<boolean> = await response.json();
46
47if (result.success) {
untitled-3016chat.ts9 matches
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { getRecentMessages, createMessage } from "../database/queries.ts";
3import type { ChatMessage, ApiResponse } from "../../shared/types.ts";
45const chat = new Hono();
9try {
10const messages = await getRecentMessages(50);
11const response: ApiResponse<ChatMessage[]> = {
12success: true,
13data: messages
15return c.json(response);
16} catch (error) {
17const response: ApiResponse<ChatMessage[]> = {
18success: false,
19error: "Failed to fetch messages"
30// Basic validation
31if (!messageData.username || !messageData.message) {
32const response: ApiResponse<ChatMessage> = {
33success: false,
34error: "Username and message are required"
40const trimmedMessage = messageData.message.trim();
41if (trimmedMessage.length === 0) {
42const response: ApiResponse<ChatMessage> = {
43success: false,
44error: "Message cannot be empty"
4849if (trimmedMessage.length > 500) {
50const response: ApiResponse<ChatMessage> = {
51success: false,
52error: "Message too long (max 500 characters)"
58const trimmedUsername = messageData.username.trim();
59if (trimmedUsername.length === 0 || trimmedUsername.length > 50) {
60const response: ApiResponse<ChatMessage> = {
61success: false,
62error: "Username must be 1-50 characters"
70});
7172const response: ApiResponse<ChatMessage> = {
73success: true,
74data: newMessage
76return c.json(response, 201);
77} catch (error) {
78const response: ApiResponse<ChatMessage> = {
79success: false,
80error: "Failed to send message"
untitled-3016jobs.ts11 matches
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { getAllJobs, createJob, deleteJob } from "../database/queries.ts";
3import type { Job, ApiResponse } from "../../shared/types.ts";
45const jobs = new Hono();
9try {
10const jobList = await getAllJobs();
11const response: ApiResponse<Job[]> = {
12success: true,
13data: jobList
15return c.json(response);
16} catch (error) {
17const response: ApiResponse<Job[]> = {
18success: false,
19error: "Failed to fetch jobs"
31if (!jobData.title || !jobData.company || !jobData.description ||
32!jobData.location || !jobData.contact_email) {
33const response: ApiResponse<Job> = {
34success: false,
35error: "Missing required fields"
41const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
42if (!emailRegex.test(jobData.contact_email)) {
43const response: ApiResponse<Job> = {
44success: false,
45error: "Invalid email format"
4950const newJob = await createJob(jobData);
51const response: ApiResponse<Job> = {
52success: true,
53data: newJob
55return c.json(response, 201);
56} catch (error) {
57const response: ApiResponse<Job> = {
58success: false,
59error: "Failed to create job"
68const id = parseInt(c.req.param("id"));
69if (isNaN(id)) {
70const response: ApiResponse<boolean> = {
71success: false,
72error: "Invalid job ID"
77const deleted = await deleteJob(id);
78if (!deleted) {
79const response: ApiResponse<boolean> = {
80success: false,
81error: "Job not found"
84}
8586const response: ApiResponse<boolean> = {
87success: true,
88data: true
90return c.json(response);
91} catch (error) {
92const response: ApiResponse<boolean> = {
93success: false,
94error: "Failed to delete job"
20const fetchOrders = async () => {
21try {
22const response = await fetch('/api/orders');
23const result = await response.json();
24if (result.success) {
untitled-3016types.ts1 match
19}
2021export interface ApiResponse<T> {
22success: boolean;
23data?: T;
untitled-3016README.md8 matches
17โ โ โโโ queries.ts # Database query functions
18โ โโโ routes/
19โ โ โโโ jobs.ts # Job posting API routes
20โ โ โโโ chat.ts # Chat API routes
21โ โโโ index.ts # Main Hono server
22โโโ frontend/
32```
3334## API Endpoints
3536### Jobs
37- `GET /api/jobs` - Get all job postings
38- `POST /api/jobs` - Create a new job posting
39- `DELETE /api/jobs/:id` - Delete a job posting
4041### Chat
42- `GET /api/chat/messages` - Get recent chat messages
43- `POST /api/chat/messages` - Send a new chat message
4445## Database Schema