Ullaas commited on
Commit
d0000ba
·
verified ·
1 Parent(s): 1626b55

Upload 15 files

Browse files
Files changed (15) hide show
  1. App.css +38 -0
  2. App.js +15 -0
  3. App.test.js +13 -0
  4. ExamplePrompts.css +64 -0
  5. ExamplePrompts.js +19 -0
  6. Landing.css +76 -0
  7. Landing.js +78 -0
  8. Layout.css +52 -0
  9. Layout.js +29 -0
  10. StoryGenerator.js +48 -0
  11. index.css +13 -0
  12. index.js +17 -0
  13. logo.svg +1 -0
  14. reportWebVitals.js +13 -0
  15. setupTests.js +5 -0
App.css ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .App {
2
+ text-align: center;
3
+ }
4
+
5
+ .App-logo {
6
+ height: 40vmin;
7
+ pointer-events: none;
8
+ }
9
+
10
+ @media (prefers-reduced-motion: no-preference) {
11
+ .App-logo {
12
+ animation: App-logo-spin infinite 20s linear;
13
+ }
14
+ }
15
+
16
+ .App-header {
17
+ background-color: #282c34;
18
+ min-height: 100vh;
19
+ display: flex;
20
+ flex-direction: column;
21
+ align-items: center;
22
+ justify-content: center;
23
+ font-size: calc(10px + 2vmin);
24
+ color: white;
25
+ }
26
+
27
+ .App-link {
28
+ color: #61dafb;
29
+ }
30
+
31
+ @keyframes App-logo-spin {
32
+ from {
33
+ transform: rotate(0deg);
34
+ }
35
+ to {
36
+ transform: rotate(360deg);
37
+ }
38
+ }
App.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from "react";
2
+ import Layout from "./Layout";
3
+ import Landing from "./Landing";
4
+ import './App.css';
5
+
6
+ export default function App() {
7
+ const [selectedPrompt, setSelectedPrompt] = useState("");
8
+
9
+ return (
10
+ <Layout onPromptSelect={setSelectedPrompt}>
11
+ <Landing initialPrompt={selectedPrompt} />
12
+ </Layout>
13
+ );
14
+ }
15
+
App.test.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from "react";
2
+ import Layout from "./Layout";
3
+ import Landing from "./Landing";
4
+
5
+ export default function App() {
6
+ const [selectedPrompt, setSelectedPrompt] = useState("");
7
+
8
+ return (
9
+ <Layout onPromptSelect={setSelectedPrompt}>
10
+ <Landing initialPrompt={selectedPrompt} />
11
+ </Layout>
12
+ );
13
+ }
ExamplePrompts.css ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .example-prompts-box {
2
+ background-color: #2a2c37;
3
+ border: 1.5px solid #565867;
4
+ border-radius: 8px;
5
+ padding: 15px 20px;
6
+ margin-bottom: 20px;
7
+ max-width: 700px;
8
+ color: #e5e5e5;
9
+ font-family: Arial, sans-serif;
10
+ }
11
+
12
+ .example-prompts-box h3 {
13
+ margin-top: 0;
14
+ margin-bottom: 12px;
15
+ color: #5671f5;
16
+ font-weight: 700;
17
+ font-size: 18px;
18
+ }
19
+
20
+ .example-prompts-box ul {
21
+ list-style: none;
22
+ padding-left: 0;
23
+ margin: 0;
24
+ }
25
+
26
+ .example-prompts-box li {
27
+ cursor: pointer;
28
+ padding: 8px 10px;
29
+ border-radius: 5px;
30
+ margin-bottom: 10px;
31
+ transition: background-color 0.2s ease;
32
+ font-size: 14px;
33
+ line-height: 1.4;
34
+ }
35
+
36
+ .example-prompts-box li:hover,
37
+ .example-prompts-box li:focus {
38
+ background-color: #5671f5;
39
+ color: white;
40
+ outline: none;
41
+ }
42
+ .example-prompts-box li {
43
+ cursor: pointer;
44
+ padding: 12px 14px;
45
+ border-radius: 8px;
46
+ margin-bottom: 12px;
47
+ background-color: #2f3240;
48
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.7);
49
+ transition: background-color 0.2s ease, box-shadow 0.3s ease;
50
+ font-size: 14px;
51
+ line-height: 1.4;
52
+ color: #e5e5e5;
53
+ }
54
+
55
+ .example-prompts-box li:hover,
56
+ .example-prompts-box li:focus {
57
+ background-color: #5671f5;
58
+ color: white;
59
+ box-shadow:
60
+ 0 4px 12px rgba(86, 113, 245, 0.7),
61
+ inset 0 0 6px 2px rgba(255, 255, 255, 0.2);
62
+ outline: none;
63
+ }
64
+
ExamplePrompts.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import "./ExamplePrompts.css";
3
+
4
+ export default function ExamplePrompts({ prompts, onSelect }) {
5
+ return (
6
+ <div className="example-prompts-box">
7
+ <h3>Example Prompts</h3>
8
+ <ul>
9
+ {prompts.map((prompt, i) => (
10
+ <li key={i} onClick={() => onSelect(prompt)} tabIndex={0} onKeyDown={e => {
11
+ if(e.key === 'Enter' || e.key === ' ') onSelect(prompt);
12
+ }}>
13
+ {prompt}
14
+ </li>
15
+ ))}
16
+ </ul>
17
+ </div>
18
+ );
19
+ }
Landing.css ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .container {
2
+ width: 100vw;
3
+ height: 100vh;
4
+ padding: 40px 20px;
5
+ box-sizing: border-box;
6
+ font-family: Arial, sans-serif;
7
+ color: #e5e5e5;
8
+ background-color: #202123;
9
+ display: flex;
10
+ flex-direction: column;
11
+ align-items: center;
12
+ justify-content: flex-start;
13
+ overflow: auto;
14
+ }
15
+
16
+ .content {
17
+ max-width: 700px;
18
+ width: 100%;
19
+ }
20
+
21
+ .heading {
22
+ margin-bottom: 10px;
23
+ text-align: center;
24
+ }
25
+
26
+ .description {
27
+ margin-bottom: 20px;
28
+ line-height: 1.5;
29
+ color: #ccc;
30
+ text-align: center;
31
+ }
32
+
33
+ .textarea {
34
+ width: 100%;
35
+ padding: 12px;
36
+ border-radius: 6px;
37
+ border: 1.5px solid #565867;
38
+ background-color: #40414f;
39
+ color: #e5e5e5;
40
+ font-size: 16px;
41
+ margin-bottom: 20px;
42
+ resize: vertical;
43
+ font-family: inherit;
44
+ }
45
+
46
+ .button {
47
+ background-color: #5671f5;
48
+ border: none;
49
+ border-radius: 6px;
50
+ padding: 14px 0;
51
+ width: 100%;
52
+ color: white;
53
+ font-weight: 700;
54
+ font-size: 16px;
55
+ cursor: pointer;
56
+ margin-bottom: 20px;
57
+ transition: background-color 0.3s ease;
58
+ }
59
+
60
+ .button:hover {
61
+ background-color: #3753d4;
62
+ }
63
+
64
+ .output {
65
+ background-color: #343541;
66
+ border-radius: 6px;
67
+ padding: 18px;
68
+ height: 250px;
69
+ overflow-y: auto;
70
+ white-space: pre-wrap;
71
+ color: #e5e5e5;
72
+ border: 1.5px solid #565867;
73
+ box-shadow: inset 0 0 8px #1c1c1f;
74
+ font-family: 'Courier New', Courier, monospace;
75
+ font-size: 15px;
76
+ }
Landing.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from "react";
2
+ import ExamplePrompts from "./ExamplePrompts";
3
+ import "./Landing.css";
4
+
5
+ const examplePromptsList = [
6
+ "Write a romantic comedy set in New York.",
7
+ "Generate a thriller about a detective chasing a serial killer.",
8
+ "Create a sci-fi scene on a distant planet.",
9
+ "Write a dialogue between two estranged siblings.",
10
+ "Outline a fantasy adventure with dragons and magic.",
11
+ ];
12
+
13
+ export default function Landing({ initialPrompt }) {
14
+ const [prompt, setPrompt] = useState(initialPrompt || "");
15
+ const [output, setOutput] = useState(
16
+ "Your screenplay output will appear here..."
17
+ );
18
+ const [loading, setLoading] = useState(false);
19
+
20
+ useEffect(() => {
21
+ if (initialPrompt) setPrompt(initialPrompt);
22
+ }, [initialPrompt]);
23
+
24
+ async function generate() {
25
+ setLoading(true);
26
+ setOutput("Generating screenplay...");
27
+ try {
28
+ const response = await fetch("http://localhost:8000/generate-story", {
29
+ method: "POST",
30
+ headers: { "Content-Type": "application/json" },
31
+ body: JSON.stringify({ user_input: prompt }),
32
+ });
33
+ if (!response.ok) {
34
+ throw new Error("Backend error: " + response.status);
35
+ }
36
+ const data = await response.json();
37
+ setOutput(
38
+ `Genre: ${data.genre || ''}\n` +
39
+ `Tone: ${data.tone || ''}\n\n` +
40
+ `Outline:\n${data.outline || ''}\n\n` +
41
+ `Scene:\n${data.scene || ''}\n\n` +
42
+ `Dialogue:\n${data.dialogue || ''}`
43
+ );
44
+ } catch (error) {
45
+ setOutput("Error generating screenplay: " + error.message);
46
+ } finally {
47
+ setLoading(false);
48
+ }
49
+ }
50
+
51
+ return (
52
+ <div className="container">
53
+ <div className="content">
54
+ <h1 className="heading">Screenplay Generator</h1>
55
+ <p className="description">
56
+ Simply provide a brief prompt, and this AI will craft a complete screenplay tailored to your idea — seamlessly weaving together the genre, plot outline, character development, and dialogue to bring your story to life.
57
+ </p>
58
+
59
+ {/* Example prompts box */}
60
+ <ExamplePrompts prompts={examplePromptsList} onSelect={setPrompt} />
61
+
62
+ <textarea
63
+ className="textarea"
64
+ value={prompt}
65
+ onChange={(e) => setPrompt(e.target.value)}
66
+ placeholder="Enter your prompt here..."
67
+ rows={6}
68
+ />
69
+
70
+ <button className="button" onClick={generate} disabled={loading}>
71
+ {loading ? "Generating..." : "Generate Screenplay"}
72
+ </button>
73
+
74
+ <pre className="output" style={{ whiteSpace: 'pre-wrap' }}>{output}</pre>
75
+ </div>
76
+ </div>
77
+ );
78
+ }
Layout.css ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .layout-container {
2
+ display: flex;
3
+ height: 100vh;
4
+ background-color: #202123;
5
+ color: #e5e5e5;
6
+ font-family: Arial, sans-serif;
7
+ }
8
+
9
+ .sidebar {
10
+ width: 320px;
11
+ background-color: #2a2c37;
12
+ padding: 20px;
13
+ box-sizing: border-box;
14
+ border-right: 1px solid #565867;
15
+ overflow-y: auto;
16
+ }
17
+
18
+ .sidebar h2 {
19
+ margin-top: 0;
20
+ margin-bottom: 15px;
21
+ font-weight: 700;
22
+ font-size: 20px;
23
+ color: #5671f5;
24
+ }
25
+
26
+ .sidebar ul {
27
+ list-style: none;
28
+ padding: 0;
29
+ margin: 0;
30
+ }
31
+
32
+ .sidebar li {
33
+ cursor: pointer;
34
+ margin-bottom: 12px;
35
+ padding: 10px;
36
+ border-radius: 6px;
37
+ transition: background-color 0.2s ease;
38
+ font-size: 14px;
39
+ line-height: 1.4;
40
+ }
41
+
42
+ .sidebar li:hover {
43
+ background-color: #5671f5;
44
+ color: white;
45
+ }
46
+
47
+ .main-content {
48
+ flex-grow: 1;
49
+ padding: 40px 30px;
50
+ box-sizing: border-box;
51
+ overflow-y: auto;
52
+ }
Layout.js ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import "./Layout.css";
3
+
4
+ export default function Layout({ children, onPromptSelect }) {
5
+ const examplePrompts = [
6
+ "Provide a simple idea, and the AI will generate a full screenplay — from genre to characters and dialogue — tailored just for you.",
7
+ "Type a concept or theme, and watch as the AI builds a complete screenplay with plot, scenes, characters, and conversations.",
8
+ "Enter a short prompt, and this AI crafts an engaging screenplay by designing the story’s genre, plot, characters, and dialogue automatically.",
9
+ "Give your story idea, and the AI will write a polished screenplay including genre, storyline, character arcs, and authentic dialogue.",
10
+ "Share a brief prompt and let the AI transform it into a full screenplay, developing the plot, characters, genre, and conversations effortlessly.",
11
+ ];
12
+
13
+ return (
14
+ <div className="layout-container">
15
+ <aside className="sidebar">
16
+ <h2>Example Prompts</h2>
17
+ <ul>
18
+ {examplePrompts.map((prompt, idx) => (
19
+ <li key={idx} onClick={() => onPromptSelect(prompt)}>
20
+ {prompt}
21
+ </li>
22
+ ))}
23
+ </ul>
24
+ </aside>
25
+
26
+ <main className="main-content">{children}</main>
27
+ </div>
28
+ );
29
+ }
StoryGenerator.js ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from "react";
2
+
3
+ function StoryGenerator() {
4
+ const [input, setInput] = useState("");
5
+ const [result, setResult] = useState(null);
6
+ const [loading, setLoading] = useState(false);
7
+
8
+ const handleSubmit = async (e) => {
9
+ e.preventDefault();
10
+ setLoading(true);
11
+ const response = await fetch("http://localhost:8000/generate-story", {
12
+ method: "POST",
13
+ headers: { "Content-Type": "application/json" },
14
+ body: JSON.stringify({ user_input: input }),
15
+ });
16
+ const data = await response.json();
17
+ setResult(data);
18
+ setLoading(false);
19
+ };
20
+
21
+ return (
22
+ <div>
23
+ <form onSubmit={handleSubmit}>
24
+ <input
25
+ value={input}
26
+ onChange={(e) => setInput(e.target.value)}
27
+ placeholder="Enter your story idea"
28
+ />
29
+ <button type="submit">Generate Story</button>
30
+ </form>
31
+ {loading && <p>Generating...</p>}
32
+ {result && (
33
+ <div>
34
+ <h3>Genre: {result.genre}</h3>
35
+ <h3>Tone: {result.tone}</h3>
36
+ <h4>Outline:</h4>
37
+ <pre>{result.outline}</pre>
38
+ <h4>Scene:</h4>
39
+ <pre>{result.scene}</pre>
40
+ <h4>Dialogue:</h4>
41
+ <pre>{result.dialogue}</pre>
42
+ </div>
43
+ )}
44
+ </div>
45
+ );
46
+ }
47
+
48
+ export default StoryGenerator;
index.css ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ margin: 0;
3
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5
+ sans-serif;
6
+ -webkit-font-smoothing: antialiased;
7
+ -moz-osx-font-smoothing: grayscale;
8
+ }
9
+
10
+ code {
11
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12
+ monospace;
13
+ }
index.js ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import './index.css';
4
+ import App from './App';
5
+ import reportWebVitals from './reportWebVitals';
6
+
7
+ const root = ReactDOM.createRoot(document.getElementById('root'));
8
+ root.render(
9
+ <React.StrictMode>
10
+ <App />
11
+ </React.StrictMode>
12
+ );
13
+
14
+ // If you want to start measuring performance in your app, pass a function
15
+ // to log results (for example: reportWebVitals(console.log))
16
+ // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17
+ reportWebVitals();
logo.svg ADDED
reportWebVitals.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const reportWebVitals = onPerfEntry => {
2
+ if (onPerfEntry && onPerfEntry instanceof Function) {
3
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4
+ getCLS(onPerfEntry);
5
+ getFID(onPerfEntry);
6
+ getFCP(onPerfEntry);
7
+ getLCP(onPerfEntry);
8
+ getTTFB(onPerfEntry);
9
+ });
10
+ }
11
+ };
12
+
13
+ export default reportWebVitals;
setupTests.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ // jest-dom adds custom jest matchers for asserting on DOM nodes.
2
+ // allows you to do things like:
3
+ // expect(element).toHaveTextContent(/react/i)
4
+ // learn more: https://github.com/testing-library/jest-dom
5
+ import '@testing-library/jest-dom';