readysite / website / views / setup / ai.html
5.1 KB
ai.html
{{template "setup.html" .}}
{{define "title"}}Configure AI{{end}}
{{define "content"}}
<h2 class="text-xl font-bold mb-4">Configure AI Assistant</h2>
<p class="text-base-content/70 mb-6">
    ReadySite uses AI to help you create and manage content. Enter your API key to enable the AI assistant.
</p>

<div id="error"></div>
<form hx-post="/setup/ai" hx-target="#error" hx-swap="innerHTML" hx-disabled-elt="find [type='submit']" class="space-y-4">
    <div class="form-control">
        <label class="label">
            <span class="label-text">AI Provider</span>
        </label>
        <select name="provider" id="provider" class="select select-bordered w-full" onchange="updateProviderInfo()">
            <option value="anthropic" selected>Anthropic (Claude) - Recommended</option>
            <option value="openai">OpenAI</option>
            <option value="mock">Mock (for testing only)</option>
        </select>
    </div>

    <div id="api-key-section">
        <div class="form-control">
            <label class="floating-label">
                <span>API Key</span>
                <input type="password" name="api_key" id="api_key" placeholder="sk-ant-..." class="input input-bordered w-full" />
            </label>
            <label class="label">
                <span class="label-text-alt text-base-content/50" id="api-key-hint">
                    Get your API key from <a href="https://console.anthropic.com/settings/keys" target="_blank" class="link link-primary">console.anthropic.com</a>
                </span>
            </label>
        </div>
    </div>

    <div class="form-control">
        <label class="label">
            <span class="label-text">Model</span>
        </label>
        <select name="model" id="model" class="select select-bordered w-full">
            <optgroup label="Anthropic" id="anthropic-models">
                <option value="claude-sonnet-4-5-20250929" selected>Claude Sonnet 4.5 (Recommended)</option>
                <option value="claude-opus-4-5-20251101">Claude Opus 4.5</option>
            </optgroup>
            <optgroup label="OpenAI" id="openai-models" class="hidden">
                <option value="gpt-4o">GPT-4o (Recommended)</option>
                <option value="gpt-4-turbo">GPT-4 Turbo</option>
            </optgroup>
        </select>
        <label class="label">
            <span class="label-text-alt text-base-content/50">The AI model to use for generating content</span>
        </label>
    </div>

    <div id="mock-warning" class="alert alert-warning text-sm hidden">
        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
        </svg>
        <span>Mock mode is for testing only. AI features will not work properly without a real API key.</span>
    </div>

    <div class="flex gap-2 mt-6">
        <a href="/setup/complete" class="btn btn-ghost flex-1">Skip for now</a>
        <button type="submit" class="btn btn-primary flex-1">
            Save & Continue
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6" />
            </svg>
        </button>
    </div>
</form>

<script>
function updateProviderInfo() {
    const provider = document.getElementById('provider').value;
    const apiKeySection = document.getElementById('api-key-section');
    const apiKeyHint = document.getElementById('api-key-hint');
    const mockWarning = document.getElementById('mock-warning');
    const model = document.getElementById('model');
    const anthropicModels = document.getElementById('anthropic-models');
    const openaiModels = document.getElementById('openai-models');

    if (provider === 'mock') {
        apiKeySection.classList.add('hidden');
        mockWarning.classList.remove('hidden');
        model.closest('.form-control').classList.add('hidden');
    } else {
        apiKeySection.classList.remove('hidden');
        mockWarning.classList.add('hidden');
        model.closest('.form-control').classList.remove('hidden');

        if (provider === 'anthropic') {
            apiKeyHint.innerHTML = 'Get your API key from <a href="https://console.anthropic.com/settings/keys" target="_blank" class="link link-primary">console.anthropic.com</a>';
            anthropicModels.classList.remove('hidden');
            openaiModels.classList.add('hidden');
            model.value = 'claude-sonnet-4-5-20250929';
        } else if (provider === 'openai') {
            apiKeyHint.innerHTML = 'Get your API key from <a href="https://platform.openai.com/api-keys" target="_blank" class="link link-primary">platform.openai.com</a>';
            anthropicModels.classList.add('hidden');
            openaiModels.classList.remove('hidden');
            model.value = 'gpt-4o';
        }
    }
}
</script>
{{end}}
← Back