aboutsummaryrefslogtreecommitdiff
path: root/cmds/templates
diff options
context:
space:
mode:
authorSam Scholten2025-12-15 19:34:17 +1000
committerSam Scholten2025-12-15 19:34:59 +1000
commit9f5978186ac3de07f4325975fecf4f538fe713b6 (patch)
tree41440b703054fe59eb561ba81d80fd60380c1f7a /cmds/templates
downloadscholscan-9f5978186ac3de07f4325975fecf4f538fe713b6.tar.gz
scholscan-9f5978186ac3de07f4325975fecf4f538fe713b6.zip
Init v0.1.0
Diffstat (limited to 'cmds/templates')
-rw-r--r--cmds/templates/live-feed.html158
-rw-r--r--cmds/templates/results.html279
-rw-r--r--cmds/templates/tools.html202
3 files changed, 639 insertions, 0 deletions
diff --git a/cmds/templates/live-feed.html b/cmds/templates/live-feed.html
new file mode 100644
index 0000000..1529ee1
--- /dev/null
+++ b/cmds/templates/live-feed.html
@@ -0,0 +1,158 @@
+{{define "live-feed"}}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{{.Title}} - Live Feed</title>
+ <style>
+ /* ========================================
+ BASE STYLE
+ ======================================== */
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: monospace;
+ background: #fff;
+ color: #000;
+ padding: 20px;
+ line-height: 1.6;
+ }
+ h1 {
+ font-size: 1.2em;
+ font-weight: bold;
+ margin-bottom: 20px;
+ }
+
+ /* ========================================
+ NAV (live-feed | score-scan)
+ ======================================== */
+ .nav {
+ margin-bottom: 30px;
+ display: flex;
+ gap: 30px;
+ border-bottom: 1px solid #000;
+ padding-bottom: 10px;
+ }
+ .nav a {
+ text-decoration: none;
+ color: #000;
+ font-family: monospace;
+ }
+ .nav a.active {
+ border-bottom: 2px solid #000;
+ padding-bottom: 5px;
+ }
+
+ /* ========================================
+ ARTICLE LIST
+ ======================================== */
+ .article {
+ margin-bottom: 15px;
+ padding: 10px;
+ border: 1px solid #ccc;
+ }
+ .article a {
+ color: #00f;
+ text-decoration: underline;
+ }
+ .article-meta {
+ margin-top: 8px;
+ color: #666;
+ font-size: 0.9em;
+ }
+
+ /* ========================================
+ ARTICLE LIST STUFF
+ ======================================== */
+ .summary {
+ margin-bottom: 15px;
+ padding: 10px;
+ border: 1px solid #000;
+ background: #f9f9f9;
+ }
+ .rss-link {
+ background: #f9f9f9;
+ padding: 15px;
+ border: 1px solid #000;
+ margin-bottom: 20px;
+ }
+ .rss-link a {
+ color: #00f;
+ text-decoration: underline;
+ }
+ .feed-list {
+ max-height: 600px;
+ overflow-y: auto;
+ border: 1px solid #000;
+ padding: 10px;
+ }
+
+ .error {
+ color: #f00;
+ margin-top: 10px;
+ padding: 10px;
+ border: 1px solid #f00;
+ }
+ </style>
+</head>
+<body>
+ <h1><a href="/live-feed" style="color: inherit; text-decoration: none;">{{.Title}}</a></h1>
+ <div class="nav">
+ <a href="/live-feed" class="active">Live Feed</a>
+ <a href="/tools">Score & Scan</a>
+ </div>
+
+ <div class="rss-link">
+ <strong>Filtered RSS Feed:</strong>
+ <a href="/api/filtered/rss" target="_blank">Subscribe to filtered articles</a>
+ <span style="margin-left: 10px; color: #666; font-size: 0.9em;">(rss link for feed readers)</span>
+ <div style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #ccc; color: #666; font-size: 0.9em;">
+ Last updated: <span id="feedTimestamp">{{if .UpdatedAt}}{{.UpdatedAt}}{{else}}—{{end}}</span>
+ </div>
+ </div>
+
+ <div style="margin-bottom: 20px;">
+ <strong>Filter by date:</strong>
+ <div style="margin-top: 8px; display: flex; gap: 10px;">
+ <a href="/live-feed?filter=day" style="padding: 6px 12px; text-decoration: none; {{if eq .Filter "day"}}background: #000; color: #fff;{{else}}border: 1px solid #000; color: #000;{{end}}">Last 24h</a>
+ <a href="/live-feed?filter=week" style="padding: 6px 12px; text-decoration: none; {{if eq .Filter "week"}}background: #000; color: #fff;{{else}}border: 1px solid #000; color: #000;{{end}}">Last 7 days</a>
+ <a href="/live-feed?filter=all" style="padding: 6px 12px; text-decoration: none; {{if eq .Filter "all"}}background: #000; color: #fff;{{else}}border: 1px solid #000; color: #000;{{end}}">All</a>
+ </div>
+ </div>
+
+ <div class="feed-list">
+ {{if .Error}}
+ <div class="error">{{.Error}}</div>
+ {{else if .Articles}}
+ <div class="summary">
+ <strong>{{len .Articles}}</strong> articles (threshold: {{printf "%.2f" .Threshold}})
+ </div>
+ {{$threshold := .Threshold}}
+ {{range .Articles}}
+ {{$isGood := ge .Score $threshold}}
+ {{$bgColor := "white"}}
+ {{if $isGood}}
+ {{$bgColor = "#e8f5e9"}}
+ {{else}}
+ {{$bgColor = "#ffebee"}}
+ {{end}}
+ {{$indicator := "✗"}}
+ {{if $isGood}}
+ {{$indicator = "✓"}}
+ {{end}}
+ <div class="article" style="background-color: {{$bgColor}};">
+ <div style="font-weight: bold;">
+ <a href="{{.URL}}" target="_blank">{{.Title}}</a>
+ </div>
+ <div class="article-meta">
+ Rating: {{$indicator}} {{.Rating}}/10 (raw: {{printf "%.3f" .Score}}) · {{.Source}}{{if .PublishedAt}} · {{.PublishedAt}}{{end}}
+ </div>
+ </div>
+ {{end}}
+ {{else}}
+ <p>No articles to display</p>
+ {{end}}
+ </div>
+</body>
+</html>
+{{end}}
diff --git a/cmds/templates/results.html b/cmds/templates/results.html
new file mode 100644
index 0000000..13f68e0
--- /dev/null
+++ b/cmds/templates/results.html
@@ -0,0 +1,279 @@
+{{define "results"}}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{{.PageTitle}} - Results</title>
+ <style>
+ /* ========================================
+ BASE STYLE
+ ======================================== */
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: monospace;
+ background: #fff;
+ color: #000;
+ padding: 20px;
+ line-height: 1.6;
+ }
+ h1 {
+ font-size: 1.2em;
+ font-weight: bold;
+ margin-bottom: 20px;
+ }
+ h2 {
+ font-size: 1em;
+ font-weight: bold;
+ margin-bottom: 15px;
+ border-bottom: 1px solid #000;
+ padding-bottom: 10px;
+ }
+
+ /* ========================================
+ NAV (live-feed | score-scan)
+ ======================================== */
+ .nav {
+ margin-bottom: 30px;
+ display: flex;
+ gap: 30px;
+ border-bottom: 1px solid #000;
+ padding-bottom: 10px;
+ }
+ .nav a {
+ text-decoration: none;
+ color: #000;
+ font-family: monospace;
+ }
+ .nav a.active {
+ border-bottom: 2px solid #000;
+ padding-bottom: 5px;
+ }
+
+ /* ========================================
+ LAYOUT (2-column grid for score-scan)
+ ======================================== */
+ .container {
+ max-width: 1200px;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 30px;
+ }
+ .section {
+ border: 1px solid #000;
+ padding: 20px;
+ }
+
+ /* ========================================
+ FORMS (input, textarea, button)
+ ======================================== */
+ label {
+ display: block;
+ margin-top: 15px;
+ font-weight: bold;
+ }
+ input, textarea {
+ display: block;
+ width: 100%;
+ margin-top: 5px;
+ padding: 5px;
+ border: 1px solid #000;
+ font-family: monospace;
+ }
+ textarea {
+ resize: vertical;
+ min-height: 80px;
+ }
+ button {
+ margin-top: 15px;
+ padding: 5px 15px;
+ border: 1px solid #000;
+ background: #fff;
+ cursor: pointer;
+ font-family: monospace;
+ }
+ button:hover {
+ background: #000;
+ color: #fff;
+ }
+ button:active {
+ opacity: 0.8;
+ }
+
+ /* ========================================
+ RESULT BOXES
+ ======================================== */
+ .result {
+ margin-top: 20px;
+ padding: 15px;
+ border: 1px solid #000;
+ background: #f5f5f5;
+ }
+ .score {
+ font-size: 3em;
+ font-weight: bold;
+ text-align: center;
+ margin: 20px 0;
+ }
+ .error {
+ color: #f00;
+ margin-top: 10px;
+ padding: 10px;
+ border: 1px solid #f00;
+ }
+
+ /* ========================================
+ ARTICLE LIST
+ ======================================== */
+ .article {
+ margin-bottom: 15px;
+ padding: 10px;
+ border: 1px solid #ccc;
+ }
+ .article a {
+ color: #00f;
+ text-decoration: underline;
+ }
+ .article-meta {
+ margin-top: 8px;
+ color: #666;
+ font-size: 0.9em;
+ }
+
+ /* ========================================
+ ARTICLE LIST STUFF
+ ======================================== */
+ .summary {
+ margin-bottom: 15px;
+ padding: 10px;
+ border: 1px solid #000;
+ background: #f9f9f9;
+ }
+
+ small {
+ display: block;
+ margin-top: 5px;
+ color: #666;
+ }
+
+ /* ========================================
+ MOBILE
+ ======================================== */
+ @media (max-width: 960px) {
+ .container {
+ grid-template-columns: 1fr;
+ gap: 20px;
+ }
+ }
+ </style>
+</head>
+<body>
+ <h1><a href="/live-feed" style="color: inherit; text-decoration: none;">{{.PageTitle}}</a></h1>
+ <div class="nav">
+ <a href="/live-feed">Live Feed</a>
+ <a href="/tools" class="active">Score & Scan</a>
+ </div>
+
+ <div class="container">
+ {{if .IsScoreResult}}
+ <div class="section">
+ <h2>Score Article</h2>
+ {{if .Error}}
+ <div class="error">{{.Error}}</div>
+ <form method="POST" action="/score" style="margin-top: 20px;">
+ <label for="scoreTitle">Title:</label>
+ <input type="text" id="scoreTitle" name="title" placeholder="Enter article title" value="{{.Title}}" />
+ <label for="scoreURL">URL or DOI:</label>
+ <input type="text" id="scoreURL" name="url" placeholder="https://example.com/article or 10.xxxx/doi" />
+ <small>If URL is provided, title will be automatically extracted</small>
+ <button type="submit">Score</button>
+ </form>
+ {{else}}
+ <div class="result">
+ <div class="score">{{.Rating}}/10</div>
+ <p style="text-align: center; color: #666;">Score: {{printf "%.3f" .Score}}</p>
+ <p style="text-align: center; margin-top: 10px; font-size: 0.9em;">{{.Title}}</p>
+ </div>
+ <form method="POST" action="/score" style="margin-top: 20px;">
+ <label for="scoreTitle">Title:</label>
+ <input type="text" id="scoreTitle" name="title" placeholder="Enter article title" />
+ <label for="scoreURL">URL or DOI:</label>
+ <input type="text" id="scoreURL" name="url" placeholder="https://example.com/article or 10.xxxx/doi" />
+ <small>If URL is provided, title will be automatically extracted</small>
+ <button type="submit">Score Another</button>
+ </form>
+ {{end}}
+ </div>
+
+ <div class="section">
+ <h2>Scan Feed</h2>
+ <form method="POST" action="/scan">
+ <label for="feedURL">RSS Feed URL:</label>
+ <input type="text" id="feedURL" name="feed_url" placeholder="https://example.com/rss.xml" required />
+ <button type="submit">Scan</button>
+ </form>
+ </div>
+
+ {{else if .IsScanResult}}
+ <div class="section">
+ <h2>Score Article</h2>
+ <form method="POST" action="/score">
+ <label for="scoreTitle">Title:</label>
+ <input type="text" id="scoreTitle" name="title" placeholder="Enter article title" />
+ <label for="scoreURL">URL or DOI:</label>
+ <input type="text" id="scoreURL" name="url" placeholder="https://example.com/article or 10.xxxx/doi" />
+ <small>If URL is provided, title will be automatically extracted</small>
+ <button type="submit">Score</button>
+ </form>
+ </div>
+
+ <div class="section">
+ <h2>Scan Feed</h2>
+ {{if .Error}}
+ <div class="error">{{.Error}}</div>
+ <form method="POST" action="/scan" style="margin-top: 20px;">
+ <label for="feedURL">RSS Feed URL:</label>
+ <input type="text" id="feedURL" name="feed_url" placeholder="https://example.com/rss.xml" value="{{.FeedURL}}" required />
+ <button type="submit">Try Again</button>
+ </form>
+ {{else}}
+ <div class="summary">
+ <strong>{{len .Articles}}</strong> articles from {{.FeedURL}} (threshold: {{printf "%.2f" .Threshold}})
+ </div>
+ <div style="max-height: 500px; overflow-y: auto; border: 1px solid #ccc; padding: 10px;">
+ {{$threshold := .Threshold}}
+ {{range .Articles}}
+ {{$isGood := ge .Score $threshold}}
+ {{$bgColor := "white"}}
+ {{if $isGood}}
+ {{$bgColor = "#e8f5e9"}}
+ {{else}}
+ {{$bgColor = "#ffebee"}}
+ {{end}}
+ {{$indicator := "✗"}}
+ {{if $isGood}}
+ {{$indicator = "✓"}}
+ {{end}}
+ <div class="article" style="background-color: {{$bgColor}};">
+ <div style="font-weight: bold;">
+ <a href="{{.URL}}" target="_blank">{{.Title}}</a>
+ </div>
+ <div class="article-meta">
+ Rating: {{$indicator}} {{.Rating}}/10 (raw: {{printf "%.3f" .Score}}) · {{.Source}}
+ </div>
+ </div>
+ {{end}}
+ </div>
+ <form method="POST" action="/scan" style="margin-top: 20px;">
+ <label for="feedURL">RSS Feed URL:</label>
+ <input type="text" id="feedURL" name="feed_url" placeholder="https://example.com/rss.xml" required />
+ <button type="submit">Scan Another</button>
+ </form>
+ {{end}}
+ </div>
+ {{end}}
+ </div>
+</body>
+</html>
+{{end}}
diff --git a/cmds/templates/tools.html b/cmds/templates/tools.html
new file mode 100644
index 0000000..def04fe
--- /dev/null
+++ b/cmds/templates/tools.html
@@ -0,0 +1,202 @@
+{{define "tools"}}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{{.Title}} - Score & Scan</title>
+ <style>
+ /* ========================================
+ BASE STYLE
+ ======================================== */
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: monospace;
+ background: #fff;
+ color: #000;
+ padding: 20px;
+ line-height: 1.6;
+ }
+ h1 {
+ font-size: 1.2em;
+ font-weight: bold;
+ margin-bottom: 20px;
+ }
+ h2 {
+ font-size: 1em;
+ font-weight: bold;
+ margin-bottom: 15px;
+ border-bottom: 1px solid #000;
+ padding-bottom: 10px;
+ }
+
+ /* ========================================
+ NAV (live-feed | score-scan)
+ ======================================== */
+ .nav {
+ margin-bottom: 30px;
+ display: flex;
+ gap: 30px;
+ border-bottom: 1px solid #000;
+ padding-bottom: 10px;
+ }
+ .nav a {
+ text-decoration: none;
+ color: #000;
+ font-family: monospace;
+ }
+ .nav a.active {
+ border-bottom: 2px solid #000;
+ padding-bottom: 5px;
+ }
+
+ /* ========================================
+ LAYOUT (2-column grid for score-scan)
+ ======================================== */
+ .container {
+ max-width: 1200px;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 30px;
+ }
+ .section {
+ border: 1px solid #000;
+ padding: 20px;
+ }
+
+ /* ========================================
+ FORMS (input, textarea, button)
+ ======================================== */
+ label {
+ display: block;
+ margin-top: 15px;
+ font-weight: bold;
+ }
+ input, textarea {
+ display: block;
+ width: 100%;
+ margin-top: 5px;
+ padding: 5px;
+ border: 1px solid #000;
+ font-family: monospace;
+ }
+ textarea {
+ resize: vertical;
+ min-height: 80px;
+ }
+ button {
+ margin-top: 15px;
+ padding: 5px 15px;
+ border: 1px solid #000;
+ background: #fff;
+ cursor: pointer;
+ font-family: monospace;
+ }
+ button:hover {
+ background: #000;
+ color: #fff;
+ }
+ button:active {
+ opacity: 0.8;
+ }
+
+ /* ========================================
+ RESULT BOXES
+ ======================================== */
+ .result {
+ margin-top: 20px;
+ padding: 15px;
+ border: 1px solid #000;
+ background: #f5f5f5;
+ }
+ .score {
+ font-size: 3em;
+ font-weight: bold;
+ text-align: center;
+ margin: 20px 0;
+ }
+ .error {
+ color: #f00;
+ margin-top: 10px;
+ padding: 10px;
+ border: 1px solid #f00;
+ }
+
+ /* ========================================
+ ARTICLE LIST
+ ======================================== */
+ .article {
+ margin-bottom: 15px;
+ padding: 10px;
+ border: 1px solid #ccc;
+ }
+ .article a {
+ color: #00f;
+ text-decoration: underline;
+ }
+ .article-meta {
+ margin-top: 8px;
+ color: #666;
+ font-size: 0.9em;
+ }
+
+ /* ========================================
+ ARTICLE LIST STUFF
+ ======================================== */
+ .summary {
+ margin-bottom: 15px;
+ padding: 10px;
+ border: 1px solid #000;
+ background: #f9f9f9;
+ }
+
+ small {
+ display: block;
+ margin-top: 5px;
+ color: #666;
+ }
+
+ /* ========================================
+ MOBILE
+ ======================================== */
+ @media (max-width: 960px) {
+ .container {
+ grid-template-columns: 1fr;
+ gap: 20px;
+ }
+ }
+ </style>
+</head>
+<body>
+ <h1><a href="/live-feed" style="color: inherit; text-decoration: none;">{{.Title}}</a></h1>
+ <div class="nav">
+ <a href="/live-feed">Live Feed</a>
+ <a href="/tools" class="active">Score & Scan</a>
+ </div>
+
+ <div class="container">
+ <div class="section">
+ <h2>Score Article</h2>
+ <form method="POST" action="/score">
+ <label for="scoreTitle">Title:</label>
+ <input type="text" id="scoreTitle" name="title" placeholder="Enter article title" />
+ <label for="scoreURL" style="margin-top: 10px;">URL or DOI:</label>
+ <input type="text" id="scoreURL" name="url" placeholder="https://example.com/article or 10.xxxx/doi" />
+ <small>If URL is provided, title will be automatically extracted</small>
+ <button type="submit">Score</button>
+ </form>
+ </div>
+
+ <div class="section">
+ <h2>Scan Feed</h2>
+ <form method="POST" action="/scan">
+ <label for="feedURL">RSS Feed URL:</label>
+ <input type="text" id="feedURL" name="feed_url" placeholder="https://example.com/rss.xml" required />
+ <button type="submit">Scan</button>
+ </form>
+ </div>
+ </div>
+</body>
+</html>
+{{end}}