refactor(ui): replace browser confirm() with ConfirmDialog component

Replace the native browser confirm() dialog in SoraAdminView with the
project's ConfirmDialog component for UI consistency.

Changes:
- Import ConfirmDialog component
- Add confirm dialog state management (showConfirmDialog, confirmDialogMessage, pendingClearUserId)
- Replace clearUserStorage() with confirmClearStorage() and handleConfirmClear()
- Add ConfirmDialog to template with danger styling
This commit is contained in:
User
2026-04-16 20:32:46 +08:00
parent db307b0d0f
commit 318c6b3743

View File

@@ -3,10 +3,9 @@ import { ref, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import soraAdminAPI, { type SoraSystemStats, type SoraUserStats, type SoraGenerationAdmin } from '@/api/admin/sora' import soraAdminAPI, { type SoraSystemStats, type SoraUserStats, type SoraGenerationAdmin } from '@/api/admin/sora'
import AppLayout from '@/components/layout/AppLayout.vue' import AppLayout from '@/components/layout/AppLayout.vue'
import LoadingSpinner from '@/components/ui/LoadingSpinner.vue' import LoadingSpinner from '@/components/common/LoadingSpinner.vue'
import Icon from '@/components/ui/Icon.vue' import Icon from '@/components/icons/Icon.vue'
import BaseButton from '@/components/ui/BaseButton.vue' import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
import BasePagination from '@/components/ui/BasePagination.vue'
const { t } = useI18n() const { t } = useI18n()
@@ -17,6 +16,11 @@ const userStats = ref<SoraUserStats[]>([])
const generations = ref<SoraGenerationAdmin[]>([]) const generations = ref<SoraGenerationAdmin[]>([])
const activeTab = ref<'overview' | 'users' | 'generations'>('overview') const activeTab = ref<'overview' | 'users' | 'generations'>('overview')
// Confirm dialog state
const showConfirmDialog = ref(false)
const confirmDialogMessage = ref('')
const pendingClearUserId = ref<number | null>(null)
// Pagination // Pagination
const userPage = ref(1) const userPage = ref(1)
const userPageSize = ref(20) const userPageSize = ref(20)
@@ -98,8 +102,19 @@ async function fetchGenerations() {
} }
} }
async function clearUserStorage(userId: number) { // Confirm dialog handlers
if (!confirm(t('admin.sora.confirmClearStorage'))) return function confirmClearStorage(userId: number) {
pendingClearUserId.value = userId
confirmDialogMessage.value = t('admin.sora.confirmClearStorage')
showConfirmDialog.value = true
}
async function handleConfirmClear() {
if (pendingClearUserId.value === null) return
const userId = pendingClearUserId.value
showConfirmDialog.value = false
pendingClearUserId.value = null
try { try {
await soraAdminAPI.clearUserStorage(userId) await soraAdminAPI.clearUserStorage(userId)
await fetchUserStats() await fetchUserStats()
@@ -109,6 +124,11 @@ async function clearUserStorage(userId: number) {
} }
} }
function handleCancelClear() {
showConfirmDialog.value = false
pendingClearUserId.value = null
}
async function loadAll() { async function loadAll() {
loading.value = true loading.value = true
await Promise.all([ await Promise.all([
@@ -304,7 +324,7 @@ onMounted(loadAll)
class="input flex-1" class="input flex-1"
@keyup.enter="fetchUserStats" @keyup.enter="fetchUserStats"
/> />
<BaseButton @click="fetchUserStats">{{ t('common.search') }}</BaseButton> <button class="btn btn-primary" @click="fetchUserStats">{{ t('common.search') }}</button>
</div> </div>
<!-- Table --> <!-- Table -->
@@ -340,13 +360,12 @@ onMounted(loadAll)
<td class="px-4 py-3 text-sm text-gray-900 dark:text-white">{{ formatBytes(user.used_bytes) }}</td> <td class="px-4 py-3 text-sm text-gray-900 dark:text-white">{{ formatBytes(user.used_bytes) }}</td>
<td class="px-4 py-3 text-sm text-gray-900 dark:text-white">{{ user.generations_count }}</td> <td class="px-4 py-3 text-sm text-gray-900 dark:text-white">{{ user.generations_count }}</td>
<td class="px-4 py-3 text-sm"> <td class="px-4 py-3 text-sm">
<BaseButton <button
variant="danger" class="btn btn-danger btn-sm"
size="sm" @click="confirmClearStorage(user.user_id)"
@click="clearUserStorage(user.user_id)"
> >
{{ t('admin.sora.clearStorage') }} {{ t('admin.sora.clearStorage') }}
</BaseButton> </button>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@@ -354,12 +373,16 @@ onMounted(loadAll)
</div> </div>
<!-- Pagination --> <!-- Pagination -->
<BasePagination <div v-if="userTotalPages > 1" class="flex items-center justify-center gap-2">
v-if="userTotalPages > 1" <button
:current="userPage" v-for="p in userTotalPages"
:total="userTotalPages" :key="p"
@change="onUserPageChange" :class="['btn btn-sm', p === userPage ? 'btn-primary' : 'btn-secondary']"
/> @click="onUserPageChange(p)"
>
{{ p }}
</button>
</div>
</div> </div>
<!-- Generations Tab --> <!-- Generations Tab -->
@@ -417,14 +440,28 @@ onMounted(loadAll)
</div> </div>
<!-- Pagination --> <!-- Pagination -->
<BasePagination <div v-if="genTotalPages > 1" class="flex items-center justify-center gap-2">
v-if="genTotalPages > 1" <button
:current="genPage" v-for="p in genTotalPages"
:total="genTotalPages" :key="p"
@change="onGenPageChange" :class="['btn btn-sm', p === genPage ? 'btn-primary' : 'btn-secondary']"
/> @click="onGenPageChange(p)"
>
{{ p }}
</button>
</div>
</div> </div>
</template> </template>
</div> </div>
<!-- Confirm Dialog -->
<ConfirmDialog
:show="showConfirmDialog"
:title="t('admin.sora.clearStorage')"
:message="confirmDialogMessage"
:danger="true"
@confirm="handleConfirmClear"
@cancel="handleCancelClear"
/>
</AppLayout> </AppLayout>
</template> </template>