|
|
|
<div
|
|
x-cloak
|
|
x-show="showAddModal"
|
|
class="fixed inset-0 overflow-y-auto z-50"
|
|
x-transition:enter="transition ease-out duration-300"
|
|
x-transition:enter-start="opacity-0"
|
|
x-transition:enter-end="opacity-100"
|
|
x-transition:leave="transition ease-in duration-200"
|
|
x-transition:leave-start="opacity-100"
|
|
x-transition:leave-end="opacity-0"
|
|
>
|
|
<div class="flex items-center justify-center min-h-screen p-4">
|
|
|
|
<div
|
|
x-cloak
|
|
@click="showAddModal = false"
|
|
x-show="showAddModal"
|
|
x-transition:enter="transition ease-out duration-300"
|
|
x-transition:enter-start="opacity-0 backdrop-blur-none"
|
|
x-transition:enter-end="opacity-80 backdrop-blur-md"
|
|
x-transition:leave="transition ease-in duration-200"
|
|
x-transition:leave-start="opacity-80 backdrop-blur-md"
|
|
x-transition:leave-end="opacity-0 backdrop-blur-none"
|
|
class="fixed inset-0 bg-gray-900/60 backdrop-blur-md"
|
|
></div>
|
|
|
|
|
|
<div
|
|
x-cloak
|
|
x-show="showAddModal"
|
|
@click.away="showAddModal = false"
|
|
x-transition:enter="transition ease-out duration-300"
|
|
x-transition:enter-start="opacity-0 transform scale-95 translate-y-4"
|
|
x-transition:enter-end="opacity-100 transform scale-100 translate-y-0"
|
|
x-transition:leave="transition ease-in duration-200"
|
|
x-transition:leave-start="opacity-100 transform scale-100 translate-y-0"
|
|
x-transition:leave-end="opacity-0 transform scale-95 translate-y-4"
|
|
class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl overflow-hidden w-4/5 max-w-3xl max-h-[80vh] z-50 relative border border-gray-200 dark:border-gray-700 flex flex-col"
|
|
>
|
|
|
|
<div class="absolute top-0 left-0 right-0 h-1.5 bg-gradient-to-r from-primary-400 via-primary-500 to-primary-600"></div>
|
|
|
|
|
|
<div class="px-6 py-4 flex justify-between items-center">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2 text-primary-500" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M18 8a6 6 0 01-7.743 5.743L10 14l-1 1-1 1H6v-1l1-1 1-1-.257-.257A6 6 0 1118 8zm-6-4a1 1 0 100 2 2 2 0 012 2 1 1 0 102 0 4 4 0 00-4-4z" clip-rule="evenodd" />
|
|
</svg>
|
|
添加新API密钥
|
|
</h3>
|
|
<button
|
|
@click="showAddModal = false"
|
|
class="text-gray-400 hover:text-gray-500 dark:text-gray-500 dark:hover:text-gray-400 transition-colors focus:outline-none rounded-full p-1"
|
|
aria-label="关闭"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
|
|
<div class="px-6 pb-6 flex-grow overflow-y-auto">
|
|
<form @submit.prevent="addApiKey()" class="space-y-5">
|
|
|
|
<div class="bg-gray-50 dark:bg-gray-700/30 rounded-lg p-4 transition-all duration-300 hover:shadow-md border border-gray-100 dark:border-gray-700">
|
|
<label for="platform" class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5 text-primary-500" viewBox="0 0 20 20" fill="currentColor">
|
|
<path d="M7 3a1 1 0 000 2h6a1 1 0 100-2H7zM4 7a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1zM2 11a2 2 0 012-2h12a2 2 0 012 2v4a2 2 0 01-2 2H4a2 2 0 01-2-2v-4z" />
|
|
</svg>
|
|
选择平台 <span class="text-red-500 ml-1">*</span>
|
|
</label>
|
|
<div class="relative">
|
|
<select
|
|
id="platform"
|
|
x-model="newKey.platform"
|
|
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm pl-3 pr-10 py-2.5 text-sm transition-colors duration-200 bg-white dark:bg-gray-700 appearance-none focus:outline-none"
|
|
required
|
|
>
|
|
<option value="" disabled>-- 选择平台 --</option>
|
|
{% for platform in platforms %}
|
|
<option value="{{ platform.id }}">{{ platform.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-500 dark:text-gray-400">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="bg-gray-50 dark:bg-gray-700/30 rounded-lg p-4 transition-all duration-300 hover:shadow-md border border-gray-100 dark:border-gray-700">
|
|
<label for="name" class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5 text-primary-500" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M10 2a1 1 0 00-1 1v1a1 1 0 002 0V3a1 1 0 00-1-1zM4 4h3a3 3 0 006 0h3a2 2 0 012 2v9a2 2 0 01-2 2H4a2 2 0 01-2-2V6a2 2 0 012-2zm2.5 7a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm2.45 4a2.5 2.5 0 10-4.9 0h4.9zM12 9a1 1 0 100 2h3a1 1 0 100-2h-3zm-1 4a1 1 0 011-1h2a1 1 0 110 2h-2a1 1 0 01-1-1z" clip-rule="evenodd" />
|
|
</svg>
|
|
密钥标识名称 <span class="text-gray-400 text-xs ml-1">(可选)</span>
|
|
</label>
|
|
<div class="mt-1 relative rounded-md shadow-sm">
|
|
<input
|
|
type="text"
|
|
id="name"
|
|
x-model="newKey.name"
|
|
placeholder="为密钥添加易于识别的名称,留空将自动生成"
|
|
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm pl-3 pr-10 py-2.5 text-sm transition-colors duration-200 focus:outline-none"
|
|
autocomplete="off"
|
|
>
|
|
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">好的命名有助于快速找到特定密钥</p>
|
|
</div>
|
|
|
|
|
|
<div class="bg-gray-50 dark:bg-gray-700/30 rounded-lg p-4 transition-all duration-300 hover:shadow-md border border-gray-100 dark:border-gray-700">
|
|
<label for="key" class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5 text-primary-500" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M18 8a6 6 0 01-7.743 5.743L10 14l-1 1-1 1H6v-1l1-1 1-1-.257-.257A6 6 0 1118 8zm-6-4a1 1 0 100 2 2 2 0 012 2 1 1 0 102 0 4 4 0 00-4-4z" clip-rule="evenodd" />
|
|
</svg>
|
|
API密钥 <span class="text-red-500 ml-1">*</span>
|
|
</label>
|
|
<div class="mt-1">
|
|
<textarea
|
|
id="key"
|
|
x-model="newKey.key"
|
|
placeholder="在此输入您的API密钥,每行一个密钥将被视为单独添加"
|
|
rows="10"
|
|
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm pl-3 pr-3 py-2.5 text-sm font-mono transition-colors duration-200 resize-none focus:outline-none"
|
|
required
|
|
spellcheck="false"
|
|
autocomplete="off"
|
|
autocorrect="off"
|
|
autocapitalize="off"
|
|
style="min-height: 200px;"
|
|
></textarea>
|
|
</div>
|
|
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">多行输入将作为多个密钥添加</p>
|
|
</div>
|
|
|
|
|
|
<div
|
|
x-show="errorMessage"
|
|
x-text="errorMessage"
|
|
class="p-3 text-sm text-red-600 bg-red-50 dark:bg-red-900/20 dark:text-red-400 rounded-lg"
|
|
></div>
|
|
|
|
|
|
<div class="flex justify-end space-x-3 mt-6">
|
|
<button
|
|
type="button"
|
|
@click="showAddModal = false"
|
|
class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none transition-colors duration-200"
|
|
>
|
|
取消
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
:disabled="isSubmitting"
|
|
class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none transition-colors duration-200 space-x-2 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
<span x-show="!isSubmitting" class="flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
|
|
</svg>
|
|
添加密钥
|
|
</span>
|
|
<span x-show="isSubmitting" class="flex items-center">
|
|
<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
</svg>
|
|
处理中...
|
|
</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
|
|
<div class="absolute bottom-3 left-6 text-xs text-gray-400 dark:text-gray-500 flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5 mr-1" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2h-1V9a1 1 0 00-1-1z" clip-rule="evenodd" />
|
|
</svg>
|
|
Esc 关闭 | Alt+Enter 提交
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|