Redesign main page with minimalist "No" and move interactive UI to /playground
- Create elegant minimalist main page with centered "No" - Add automatic dark mode support for main page - Move original interactive API testing interface to /playground - Add footer links to main page for navigation - Update routing to serve both pages appropriately - Update documentation to reflect new page structure The main page now provides a clean, focused experience while the playground remains available for API testing and exploration. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
858e14a520
commit
ebd0fcc448
3 changed files with 98 additions and 5 deletions
|
|
@ -56,10 +56,13 @@ The entire application is contained in `src/main.rs` with ~372 lines of code. Th
|
||||||
|
|
||||||
### Key Components
|
### Key Components
|
||||||
|
|
||||||
1. **Embedded HTML Frontend**: The HTML/CSS/JavaScript frontend is embedded as a string constant (`HTML_FRONTEND`) directly in the source code, eliminating the need for static file serving.
|
1. **Embedded HTML Frontends**: Two HTML frontends are embedded as string constants:
|
||||||
|
- `SIMPLE_FRONTEND`: Minimalist main page with just "No" centered on screen
|
||||||
|
- `PLAYGROUND_FRONTEND`: Interactive API testing playground with buttons and examples
|
||||||
|
|
||||||
2. **Request Router**: The `route_request()` function handles all routing logic:
|
2. **Request Router**: The `route_request()` function handles all routing logic:
|
||||||
- `/` - Serves the embedded HTML frontend
|
- `/` - Serves the minimalist "No" page
|
||||||
|
- `/playground` - Serves the interactive API testing interface
|
||||||
- `/api/no` - API endpoint with format parameter support
|
- `/api/no` - API endpoint with format parameter support
|
||||||
- `/health` - Health check endpoint
|
- `/health` - Health check endpoint
|
||||||
- CORS headers are added to all responses
|
- CORS headers are added to all responses
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ A lightweight, production-ready HTTP service that always says "no" in various fo
|
||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
- `GET /` - Web frontend
|
- `GET /` - Minimalist web page displaying "No"
|
||||||
|
- `GET /playground` - Interactive API testing playground
|
||||||
- `GET /api/no` - Returns plain text "no"
|
- `GET /api/no` - Returns plain text "no"
|
||||||
- `GET /api/no?format=json` - Returns `{"answer": "no"}`
|
- `GET /api/no?format=json` - Returns `{"answer": "no"}`
|
||||||
- `GET /api/no?format=bool` - Returns `false`
|
- `GET /api/no?format=bool` - Returns `false`
|
||||||
|
|
|
||||||
93
src/main.rs
93
src/main.rs
|
|
@ -2,7 +2,95 @@ use std::io::prelude::*;
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
const HTML_FRONTEND: &str = r#"<!DOCTYPE html>
|
const SIMPLE_FRONTEND: &str = r#"<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>No</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no {
|
||||||
|
font-size: clamp(3rem, 15vw, 12rem);
|
||||||
|
font-weight: 300;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
user-select: none;
|
||||||
|
animation: subtle-fade 2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 2rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a {
|
||||||
|
color: #666;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes subtle-fade {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
background: #000000;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.footer a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="no">No</div>
|
||||||
|
<div class="footer">
|
||||||
|
<a href="/playground">Playground</a>
|
||||||
|
<span>·</span>
|
||||||
|
<a href="/api/no">API</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>"#;
|
||||||
|
|
||||||
|
const PLAYGROUND_FRONTEND: &str = r#"<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
|
@ -315,7 +403,8 @@ fn route_request(request_line: &str) -> (&str, &str, String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
match path {
|
match path {
|
||||||
"/" => ("200 OK", "text/html; charset=utf-8", HTML_FRONTEND.to_string()),
|
"/" => ("200 OK", "text/html; charset=utf-8", SIMPLE_FRONTEND.to_string()),
|
||||||
|
"/playground" => ("200 OK", "text/html; charset=utf-8", PLAYGROUND_FRONTEND.to_string()),
|
||||||
"/health" => ("200 OK", "text/plain", "OK".to_string()),
|
"/health" => ("200 OK", "text/plain", "OK".to_string()),
|
||||||
path if path.starts_with("/api/no") => handle_api_no(path),
|
path if path.starts_with("/api/no") => handle_api_no(path),
|
||||||
_ => ("404 Not Found", "text/plain", "Not Found".to_string()),
|
_ => ("404 Not Found", "text/plain", "Not Found".to_string()),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue