changeset 27:176a182c02cf

add view_course
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 01 Aug 2025 20:08:13 -0600
parents d3f5448743bf
children 99b71a377f2c
files src/chat.css src/chat.html.luan src/chat.js src/edit_course.html.luan src/lang_courses.html.luan src/site.css src/tools/markdown.html src/view_course.html.luan
diffstat 8 files changed, 92 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
diff -r d3f5448743bf -r 176a182c02cf src/chat.css
--- a/src/chat.css	Fri Aug 01 17:12:03 2025 -0600
+++ b/src/chat.css	Fri Aug 01 20:08:13 2025 -0600
@@ -36,7 +36,3 @@
 dialog[rename] input {
 	width: 300px;
 }
-
-div[system_prompt] {
-	white-space-collapse: preserve;
-}
diff -r d3f5448743bf -r 176a182c02cf src/chat.html.luan
--- a/src/chat.html.luan	Fri Aug 01 17:12:03 2025 -0600
+++ b/src/chat.html.luan	Fri Aug 01 20:08:13 2025 -0600
@@ -82,18 +82,28 @@
 		</dialog>
 		<dialog system_prompt>
 			<h2>System Prompt</h2>
-			<div system_prompt>
+			<pre>
 <%				chat.output_system_prompt() %>
-			</div>
+			</pre>
+			<p><a href="view_course.html?course=<%=chat.course_id%>">View course</a></p>
 			<div buttons>
 				<button onclick="closeModal(this)">Close</button>
 			</div>
 		</dialog>
+		<input name=initialized style="display:none">
 		<script>
 			handleMarkdown();
+			setTimeout(function(){
+				let initialized = document.querySelector('[name=initialized]');
+				if( !initialized.value ) {
+					initialized.value = 'yes';
+					//alert('init');
+					scrollToEnd();
 <%	if added_message then %>
-			playLastMessage();
+					playLastMessage();
 <%	end %>
+				}
+			},10);
 		</script>
 	</body>
 </html>
diff -r d3f5448743bf -r 176a182c02cf src/chat.js
--- a/src/chat.js	Fri Aug 01 17:12:03 2025 -0600
+++ b/src/chat.js	Fri Aug 01 20:08:13 2025 -0600
@@ -48,18 +48,16 @@
 	}
 }
 
+function scrollToEnd() {
+	window.scrollTo(0, document.body.scrollHeight);
+}
+
 function updateAi(html) {
 	hideWaitingAiIcon();
 	document.querySelector('div[messages]').insertAdjacentHTML('beforeend',html);
 	handleMarkdown();
 	document.querySelector('textarea').focus();
-	window.scrollTo(0, document.body.scrollHeight);
-/*
-	let scroll = aiDialog.querySelector('[scroll]');
-	setTimeout(function(){
-		scroll.scrollTo(0,scroll.scrollHeight);
-	});
-*/
+	scrollToEnd();
 	playLastMessage();
 }
 
diff -r d3f5448743bf -r 176a182c02cf src/edit_course.html.luan
--- a/src/edit_course.html.luan	Fri Aug 01 17:12:03 2025 -0600
+++ b/src/edit_course.html.luan	Fri Aug 01 20:08:13 2025 -0600
@@ -39,12 +39,17 @@
 			textarea {
 				display: block;
 			}
+			input[type=text],
+			textarea {
+				width: 100%;
+			}
 			h4 {
 				margin-top: 22px;
 				margin-bottom: 4px;
 			}
 			input[type=submit] {
 				margin-top: 22px;
+				margin-bottom: 22px;
 			}
 		</style>
 	</head>
@@ -59,15 +64,19 @@
 			<h3><%= course.language_name() %></h3>
 
 			<h4>Course name</h4>
-			<input required name=name value="<%=html_encode(course.name)%>">
+			<input type=text required name=name value="<%=html_encode(course.name)%>">
 
 			<h4>AI system prompt</h4>
-			<textarea required name=ai_system_prompt><%=html_encode(course.ai_system_prompt)%></textarea>
+			<textarea required name=ai_system_prompt rows=10><%=html_encode(course.ai_system_prompt)%></textarea>
 
 			<h4>AI first message (optional)</h4>
 			<textarea required name=ai_first_message><%=html_encode(course.ai_first_message or "")%></textarea>
 
 			<input type=submit>
+
+			<hr>
+
+			<p>Text areas take <a href="/tools/markdown.html">Markdown</a>.  AI generally recognizes Markdown.</p>
 		</form>
 	</body>
 </html>
diff -r d3f5448743bf -r 176a182c02cf src/lang_courses.html.luan
--- a/src/lang_courses.html.luan	Fri Aug 01 17:12:03 2025 -0600
+++ b/src/lang_courses.html.luan	Fri Aug 01 20:08:13 2025 -0600
@@ -45,6 +45,7 @@
 				<tr>
 					<td><%= course.name_html() %></td>
 					<td><a href="new_chat.red?course=<%=course.id%>">new chat</a></td>
+					<td><a href="view_course.html?course=<%=course.id%>">view</a></td>
 				</tr>
 <%	end %>
 			</table>
diff -r d3f5448743bf -r 176a182c02cf src/site.css
--- a/src/site.css	Fri Aug 01 17:12:03 2025 -0600
+++ b/src/site.css	Fri Aug 01 20:08:13 2025 -0600
@@ -9,6 +9,7 @@
 
 a {
 	text-decoration: none;
+	outline: none;
 }
 a:hover {
 	text-decoration: underline;
@@ -85,5 +86,5 @@
 
 pre,
 code {
-	text-wrap: wrap;
+	white-space: pre-wrap;
 }
diff -r d3f5448743bf -r 176a182c02cf src/tools/markdown.html
--- a/src/tools/markdown.html	Fri Aug 01 17:12:03 2025 -0600
+++ b/src/tools/markdown.html	Fri Aug 01 20:08:13 2025 -0600
@@ -2,9 +2,12 @@
 <html lang="en">
 	<head>
 		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<title>Lang</title>
 		<style>
 			@import "/site.css";
+
+			textarea {
+				width: 100%;
+			}
 		</style>
 		<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
 		<script src="/site.js"></script>
@@ -20,9 +23,10 @@
 	</head>
 	<body>
 		<div content>
+			<h1>Markdown</h1>
+			<p><a href="https://markdownlivepreview.com/">Markdown</a> is understood by AI, so you can use it to communicate more clearly with AI.  The form below renders Markdown as this website does generally.</p>
 			<form action="javascript:markdown()">
-				<h1>Markdown</h1>
-				<p><textarea rows=20 cols=80></textarea></p>
+				<p><textarea rows=20 autofocus></textarea></p>
 				<p><input type=submit></p>
 			</form>
 			<div result>
diff -r d3f5448743bf -r 176a182c02cf src/view_course.html.luan
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/view_course.html.luan	Fri Aug 01 20:08:13 2025 -0600
@@ -0,0 +1,53 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local Html = require "luan:Html.luan"
+local html_encode = Html.encode or error()
+local Io = require "luan:Io.luan"
+local Http = require "luan:http/Http.luan"
+local Shared = require "site:/lib/Shared.luan"
+local head = Shared.head or error()
+local header = Shared.header or error()
+local Course = require "site:/lib/Course.luan"
+local get_course_by_id = Course.get_by_id or error()
+
+
+return function()
+	local course_id = Http.request.parameters.course
+	local course = get_course_by_id(course_id) or error()
+	Io.stdout = Http.response.text_writer()
+%>
+<!doctype html>
+<html lang="en">
+	<head>
+<%		head() %>
+		<style>
+			h4 {
+				margin-top: 22px;
+				margin-bottom: 4px;
+			}
+		</style>
+	</head>
+	<body>
+<%		header() %>
+		<div content>
+			<input type=hidden name=language value="<%=course.language%>">
+<%	if course_id ~= nil then %>
+			<input type=hidden name=course value="<%=course_id%>">
+<%	end %>
+			<h1>View Course</h1>
+
+			<h2><%= course.name_html() %></h2>
+
+			<h3><%= course.language_name() %></h3>
+
+			<h4>AI system prompt</h4>
+			<pre><%=html_encode(course.ai_system_prompt)%></pre>
+
+			<h4>AI first message (optional)</h4>
+			<pre><%=html_encode(course.ai_first_message or "")%></pre>
+
+		</div>
+	</body>
+</html>
+<%
+end