1475
1476 // Get random quote
1477 if (url.pathname === "/api/quote/random" && request.method === "GET") {
1478 const randomIndex = Math.floor(Math.random() * quotes.length);
1479 const quote = quotes[randomIndex];
1490
1491 // Get quote by index
1492 if (url.pathname.startsWith("/api/quote/") && request.method === "GET") {
1493 const index = parseInt(url.pathname.split("/").pop());
1494 const quote = quotes.find(q => q.index === index);
1515
1516 // Get quotes by tag
1517 if (url.pathname === "/api/quote/tag" && request.method === "GET") {
1518 const tag = url.searchParams.get("tag");
1519
1543
1544 // Get quotes by author
1545 if (url.pathname === "/api/quote/author" && request.method === "GET") {
1546 const author = url.searchParams.get("author");
1547
1569
1570 // Get top quotes by likes
1571 if (url.pathname === "/api/quote/top" && request.method === "GET") {
1572 const limit = parseInt(url.searchParams.get("limit") || "10");
1573
1587
1588 // Search quotes
1589 if (url.pathname === "/api/quote/search" && request.method === "GET") {
1590 const query = url.searchParams.get("q");
1591
8import { serveFile } from "https://esm.town/v/std/utils@85-main/index.ts";
9import { Hono } from "npm:hono";
10import { addApiRoutes } from "./api.ts";
11import type { OnboardingSettings } from "./state.ts"; // Import type for clarity
12import { addTrackerRoute } from "./trackerRoute.ts";
72addTrackerRoute(app);
73
74// 2. Add API endpoints used by the tracker (reset, etc.)
75addApiRoutes(app);
76
77// 3. Serve static files from the /frontend directory (if you add any)
4const ideas = [
5 "a URL shortener",
6 "a custom API for your personal website",
7 "a weather notification bot",
8 "a tool to monitor website uptime",
10 "a simple webhook processor",
11 "a daily joke emailer",
12 "a personal habit tracker API",
13 "a stock price alerter",
14 "a meeting reminder service",
18
19const STATE_KEY = "onboardingProgressState_v2"; // Key for blob-managed state
20const SETTINGS_OVERRIDE_KEY = "onboardingSettingsOverrides_v1"; // Optional: if you want to allow API overrides
21
22// --- Settings Management ---
4
5/**
6 * Adds API routes (/api/...) to the Hono app.
7 */
8export function addApiRoutes(app: Hono) {
9 // Endpoint to reset onboarding progress and settings
10 app.post("/api/reset", async (c: Context) => {
11 try {
12 await resetOnboardingState(); // This now resets settings too
80 </div>
81 <!-- Right Actions -->
82 <button class="reset-button" onclick="if(confirm('Reset progress flags in START_HERE.ts? (You may need to manually edit the file)')) postApi('/api/reset').then(()=>window.location.reload())" title="Reset onboarding state (clears blob state)">Reset</button>
83 </div>
84 </div>
85 <script>
86 // Helper function for API calls
87 async function postApi(endpoint) {
88 try {
89 const response = await fetch(endpoint, { method: 'POST' });
90 if (!response.ok) {
91 throw new Error(`API Error: ${response.statusText}`);
92 }
93 return await response.json();
94 } catch (error) {
95 console.error('API call failed:', error);
96 alert('Operation failed: ' + error.message);
97 }
11} from "./state.ts";
12
13// Define API routes separately for clarity
14const api = new Hono();
15api.post("/reset", async (c) => {
16 await resetOnboardingState();
17 console.log("Onboarding state reset via API.");
18 return c.json({ success: true, message: "Onboarding reset" });
19});
20
21export function addTrackerRoute(app: Hono) {
22 // Mount API routes
23 app.route("/api", api);
24
25 app.get("/", async (c: Context) => {
1import { handler } from "./api.tsx";
2import { loadTypeaheadDataIntoMemory } from "./db.ts";
3
13import { searchDocs, searchDocsCount } from "./docsearch.ts";
14
15// Handle typeahead API requests
16export function handleTypeahead(req: Request): Response {
17 const url = new URL(req.url);
99 searchTerm
100 ? (needFullDocsData
101 ? searchDocs(searchTerm, page, pageSize, true) // Get full data for docs tab or JSON API
102 : searchDocsCount(searchTerm).then(count => ({ results: [], totalResults: count }))) // Just get count for other tabs in HTML view
103 : { results: [], totalResults: 0 }
85}
86
87// --- API Endpoint for Tracker Actions ---
88app.post("/api/set-feature-flag/:flagName", async (c) => {
89 const flagName = c.req.param("flagName");
90 const { enabled } = await c.req.json<{ enabled: boolean }>();
245 </div>
246 <!-- Reset Button on Right -->
247 <button class="reset-button" onclick="if(confirm('Reset onboarding progress?')) postApi('/api/reset').then(()=>window.location.reload())" title="Reset onboarding state">Reset</button>
248 </div>
249 </div>
250 <script>
251 async function postApi(url, body = {}) { try { const res = await fetch(url, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(body) }); if (!res.ok) throw new Error('API Error: ' + await res.text()); return await res.json(); } catch (e) { console.error('API Call Failed:', url, e); alert('Action failed: ' + e.message); throw e; } }
252 const learnCronBtn = document.getElementById('learn-cron-btn');
253 if (learnCronBtn) {
256 learnCronBtn.disabled = true; learnCronBtn.textContent = 'Processing...';
257 try {
258 await postApi('/api/set-feature-flag/step5_link_clicked', { enabled: true });
259 window.open(cronGuideUrl, '_blank');
260 window.location.reload();
269
270// --- Reset Endpoint ---
271app.post("/api/reset", async (c) => {
272 console.log("Resetting onboarding state (v5)...");
273 try {