Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// This app will create a confessional interface where users can input their sins
// and receive a penance in the form of Catholic prayers. We'll use React for the
// frontend and ChatGPT to determine the number of prayers based on the
// confession. The app will use server-side processing to interact with the
// OpenAI API.
/** @jsxImportSource https://esm.sh/react@18.2.0 */
import React, { useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
function App() {
const [confession, setConfession] = useState("");
const [penance, setPenance] = useState(null);
const calculatePenance = () => {
const wordCount = confession.trim().split(/\s+/).length;
const gloryBe = Math.ceil(wordCount / 10);
const ourFather = Math.ceil(wordCount / 20);
const hailMary = Math.ceil(wordCount / 15);
fetch("/penance", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ confession }),
})
.then((response) => response.text())
.then((penanceHtml) => {
// Strip out ```html and ``` if present
const penanceText = penanceHtml.replace(/```html|```/g, '');
console.log(penanceText); // For debugging
setPenance(penanceText);
})
.catch((error) => console.error("Error:", error));
};
return (
<div className="container">
<h1>Virtual Confessional</h1>
<textarea
value={confession}
onChange={(e) => setConfession(e.target.value)}
placeholder="Confess your sins here..."
rows={5}
/>
<button onClick={calculatePenance}>Receive Penance</button>
{penance && (
<div className="penance">
<h2>Your Penance:</h2>
<p dangerouslySetInnerHTML={{ __html: penance }} />
</div>
)}
<footer style={{ marginTop: '2rem', fontSize: '0.9rem', textAlign: 'center' }}>
<a href={import.meta.url.replace("esm.town", "val.town")} style={{ color: '#ffd700', textDecoration: 'none' }}>
View Source
</a>
</footer>
</div>
);
}
function client() {
createRoot(document.getElementById("root")).render(<App />);
}
if (typeof document !== "undefined") {
client();
}
// Server-side code
export default async function server(request: Request): Promise<Response> {
if (request.method === "POST" && new URL(request.url).pathname === "/penance") {
const { OpenAI } = await import("https://esm.town/v/std/openai");
const openai = new OpenAI();
const { confession } = await request.json();
const completion = await openai.chat.completions.create({
messages: [
{ role: "system", content: "You are a Catholic priest assigning penance. Respond with a short paragraph in HTML format, describing the penance in terms of Glory Be, Our Father, and Hail Mary prayers. Use <b> tags to bold the number and type of each
{ role: "user", content: `Based on this confession, assign an appropriate penance. Your response should be in HTML format with the number and type of prayers in bold: "${confession}"` },
],
model: "gpt-4-mini",
max_tokens: 150,
});
const penance = completion.choices[0].message.content.trim();
return new Response(penance, {
headers: { "Content-Type": "text/html" },
});
}
return new Response(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Virtual Confessional</title>
stevekrouse-confessionalapp.web.val.run
September 3, 2024