1// @jsxImportSource https://esm.sh/react@18.2.0
2import React from "https://esm.sh/react@18.2.0";
3
4// Navigation component props
9
10// Navigation component
11export const Navigation: React.FC<NavigationProps> = ({ activeView, onViewChange }) => {
12 return (
13 <header className="bg-blue-600 text-white shadow-md">
76
77// NavItem component
78const NavItem: React.FC<NavItemProps> = ({ label, view, activeView, onViewChange }) => {
79 const isActive = activeView === view;
80
1// @jsxImportSource https://esm.sh/react@18.2.0
2import React, { useState, useEffect } from "https://esm.sh/react@18.2.0";
3import { TRACKS, getTrackName, getTrackEmoji, getCurrentDay } from "../../shared/utils.ts";
4
27
28// Dashboard component
29export const Dashboard: React.FC<DashboardProps> = ({ onViewChange }) => {
30 const [tracks, setTracks] = useState<TrackStatus[]>([]);
31 const [todaysTasks, setTodaysTasks] = useState<Task[]>([]);
306
307// Track card component
308const TrackCard: React.FC<TrackCardProps> = ({ track, status, onViewDetails }) => {
309 return (
310 <div className="bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden">
332
333// Status badge component
334const StatusBadge: React.FC<StatusBadgeProps> = ({ status }) => {
335 let bg = "bg-gray-100";
336 let text = "text-gray-800";
362
363// Stat card component
364const StatCard: React.FC<StatCardProps> = ({ title, value, color }) => {
365 let colorClass = "text-gray-700 dark:text-gray-300";
366
1// @jsxImportSource https://esm.sh/react@18.2.0
2import React, { useState } from "https://esm.sh/react@18.2.0";
3
4// Setup form props
8
9// Setup form component
10export const SetupForm: React.FC<SetupFormProps> = ({ onComplete }) => {
11 const [personalStatus, setPersonalStatus] = useState({
12 timeAvailability: "",
20
21 // Handle input changes
22 const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
23 const { name, value } = e.target;
24 setPersonalStatus(prev => ({
29
30 // Handle form submission
31 const handleSubmit = async (e: React.FormEvent) => {
32 e.preventDefault();
33 setIsSubmitting(true);
23
24- Built on **ValTown** platform
25- Frontend: **React** with **TailwindCSS**
26- Backend: **Hono** framework with SQLite storage
27- AI Guidance: Simulated AI responses (can be replaced with actual OpenAI integration)
52โ โโโ index.ts # Main entry point
53โโโ frontend/
54โ โโโ components/ # React components
55โ โ โโโ App.tsx # Main application component
56โ โ โโโ Dashboard.tsx # Dashboard view
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import { BlueskyIcon, DiscordIcon, GitHubIcon, RSSIcon, TwitterIcon } from "./icons.tsx";
3
20
21- **`/index.ts`**: Main entry point that sets up Hono routing and middleware
22- **`/components/`**: React components for rendering the blog
23 - **`Layout.tsx`**: Shared layout with header, footer, and styling
24 - **`HomePage.tsx`**: Renders the blog homepage with featured and recent posts
37### Technical Stack
38
39- **React**: For server-side rendering components
40- **Hono**: Lightweight web framework for routing
41- **Custom CSS**: For styling (no external frameworks)
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import wrap from "https://esm.sh/word-wrap@1.2.5";
3
7 title = "Val Town Blog",
8 ...props
9}: React.SVGProps<SVGSVGElement> & {
10 title?: string;
11}) {
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import { render as renderPNG } from "https://deno.land/x/resvg_wasm@0.2.0/mod.ts";
3import { Hono } from "https://esm.sh/hono@3.12.0";
4import { renderToStaticMarkup } from "https://esm.sh/react-dom@18.2.0/server";
5import OGImage from "../components/OGImage.tsx";
6
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2
3export default function (props: React.SVGProps<SVGSVGElement>) {
4 return (
5 <svg
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2
3export default function(props: React.SVGProps<SVGSVGElement>) {
4 return (
5 <svg
18}
19
20export function Favicon(props: React.SVGProps<SVGSVGElement>) {
21 return (
22 <svg