Spaces:
Running
Running
| <script lang="ts"> | |
| import { setApiKey } from '$lib/stores/story'; | |
| export let onApiKeySet: ((apiKey: string) => void) | undefined = undefined; | |
| let inputKey = ''; | |
| let isSet = false; | |
| function handleSubmit(event: Event) { | |
| event.preventDefault(); | |
| if (inputKey.trim()) { | |
| setApiKey(inputKey.trim()); | |
| isSet = true; | |
| onApiKeySet?.(inputKey.trim()); | |
| } | |
| } | |
| function handleReset() { | |
| inputKey = ''; | |
| isSet = false; | |
| setApiKey(''); | |
| } | |
| </script> | |
| <div class="api-key-input"> | |
| {#if !isSet} | |
| <div class="input-container"> | |
| <h2>Enter OpenAI API Key</h2> | |
| <p class="description"> | |
| Your API key is used to generate the story and videos with GPT-4 and Sora. | |
| It's stored only in your browser and never sent to our servers. | |
| </p> | |
| <form on:submit={handleSubmit}> | |
| <input | |
| type="password" | |
| bind:value={inputKey} | |
| placeholder="sk-..." | |
| class="api-key-field" | |
| required | |
| /> | |
| <button type="submit" class="submit-button"> | |
| Start Adventure | |
| </button> | |
| </form> | |
| <p class="info"> | |
| Don't have an API key? Get one at <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener">OpenAI Platform</a> | |
| </p> | |
| </div> | |
| {:else} | |
| <div class="key-set"> | |
| <p>✓ API Key Set</p> | |
| <button on:click={handleReset} class="reset-button"> | |
| Change Key | |
| </button> | |
| </div> | |
| {/if} | |
| </div> | |
| <style> | |
| .api-key-input { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 2rem; | |
| min-height: 300px; | |
| } | |
| .input-container { | |
| max-width: 500px; | |
| width: 100%; | |
| text-align: center; | |
| } | |
| h2 { | |
| margin: 0 0 0.5rem 0; | |
| color: #1a1a1a; | |
| font-size: 1.75rem; | |
| } | |
| .description { | |
| color: #666; | |
| margin: 0 0 2rem 0; | |
| line-height: 1.5; | |
| font-size: 0.95rem; | |
| } | |
| form { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| } | |
| .api-key-field { | |
| padding: 0.75rem 1rem; | |
| font-size: 1rem; | |
| border: 2px solid #ddd; | |
| border-radius: 0.5rem; | |
| font-family: 'Monaco', 'Consolas', monospace; | |
| } | |
| .api-key-field:focus { | |
| outline: none; | |
| border-color: #007bff; | |
| } | |
| .submit-button { | |
| padding: 1rem 2rem; | |
| font-size: 1.1rem; | |
| font-weight: 600; | |
| background: #007bff; | |
| color: white; | |
| border: none; | |
| border-radius: 0.5rem; | |
| cursor: pointer; | |
| transition: background 0.2s; | |
| } | |
| .submit-button:hover { | |
| background: #0056b3; | |
| } | |
| .info { | |
| margin-top: 1.5rem; | |
| font-size: 0.85rem; | |
| color: #666; | |
| } | |
| .info a { | |
| color: #007bff; | |
| text-decoration: none; | |
| } | |
| .info a:hover { | |
| text-decoration: underline; | |
| } | |
| .key-set { | |
| display: flex; | |
| align-items: center; | |
| gap: 1rem; | |
| padding: 1rem 1.5rem; | |
| background: #d4edda; | |
| border: 1px solid #c3e6cb; | |
| border-radius: 0.5rem; | |
| color: #155724; | |
| } | |
| .key-set p { | |
| margin: 0; | |
| font-weight: 600; | |
| } | |
| .reset-button { | |
| padding: 0.5rem 1rem; | |
| font-size: 0.9rem; | |
| background: white; | |
| color: #155724; | |
| border: 1px solid #c3e6cb; | |
| border-radius: 0.375rem; | |
| cursor: pointer; | |
| transition: background 0.2s; | |
| } | |
| .reset-button:hover { | |
| background: #f1f1f1; | |
| } | |
| </style> | |