Files
stream.ui/src/routes/settings/DangerZone/DangerZone.vue
lethdat bd8b21955e feat: add BaseTable component for improved table rendering
- Introduced a new BaseTable component to enhance table functionality with sorting and loading states.
- Updated upload queue logic to support chunk uploads and improved error handling.
- Refactored various admin routes to utilize the new BaseTable component.
- Adjusted import paths for UI components to maintain consistency.
- Enhanced upload handling with better progress tracking and cancellation support.
- Updated theme colors in uno.config.ts for a more cohesive design.
2026-03-18 22:23:11 +07:00

150 lines
5.9 KiB
Vue

<script setup lang="ts">
import { client as rpcClient } from '@/api/rpcclient';
import AppButton from '@/components/ui/AppButton.vue';
import AlertTriangleIcon from '@/components/icons/AlertTriangle.vue';
import SlidersIcon from '@/components/icons/SlidersIcon.vue';
import TrashIcon from '@/components/icons/TrashIcon.vue';
import { useAppConfirm } from '@/composables/useAppConfirm';
import { useAppToast } from '@/composables/useAppToast';
import SettingsNotice from '@/routes/settings/components/SettingsNotice.vue';
import SettingsRow from '@/routes/settings/components/SettingsRow.vue';
import SettingsSectionCard from '@/routes/settings/components/SettingsSectionCard.vue';
import { useAuthStore } from '@/stores/auth';
import { useTranslation } from 'i18next-vue';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const auth = useAuthStore();
const router = useRouter();
const toast = useAppToast();
const confirm = useAppConfirm();
const { t } = useTranslation();
const deletingAccount = ref(false);
const clearingData = ref(false);
const handleDeleteAccount = () => {
confirm.require({
message: t('settings.dangerZone.confirm.deleteAccountMessage'),
header: t('settings.dangerZone.confirm.deleteAccountHeader'),
acceptLabel: t('settings.dangerZone.confirm.deleteAccountAccept'),
rejectLabel: t('settings.dangerZone.confirm.deleteAccountReject'),
accept: async () => {
deletingAccount.value = true;
try {
await rpcClient.deleteMe();
auth.$reset();
toast.add({
severity: 'success',
summary: t('settings.dangerZone.toast.deleteAccountSummary'),
detail: t('settings.dangerZone.toast.deleteAccountDetail'),
life: 5000,
});
await router.push('/login');
} catch (e: any) {
console.error(e);
toast.add({
severity: 'error',
summary: t('settings.dangerZone.toast.failedSummary'),
detail: e.message || t('settings.dangerZone.toast.failedDetail'),
life: 5000,
});
} finally {
deletingAccount.value = false;
}
},
});
};
const handleClearData = () => {
confirm.require({
message: t('settings.dangerZone.confirm.clearDataMessage'),
header: t('settings.dangerZone.confirm.clearDataHeader'),
acceptLabel: t('settings.dangerZone.confirm.clearDataAccept'),
rejectLabel: t('settings.dangerZone.confirm.clearDataReject'),
accept: async () => {
clearingData.value = true;
try {
await rpcClient.clearMyData();
await auth.fetchMe();
toast.add({
severity: 'success',
summary: t('settings.dangerZone.toast.clearDataSummary'),
detail: t('settings.dangerZone.toast.clearDataDetail'),
life: 5000,
});
} catch (e: any) {
console.error(e);
toast.add({
severity: 'error',
summary: t('settings.dangerZone.toast.failedSummary'),
detail: e.message || t('settings.dangerZone.toast.failedDetail'),
life: 5000,
});
} finally {
clearingData.value = false;
}
},
});
};
</script>
<template>
<SettingsSectionCard
:title="t('settings.content.danger.title')"
:description="t('settings.content.danger.subtitle')"
titleClass="text-base font-semibold text-danger"
>
<SettingsRow
:title="t('settings.dangerZone.deleteAccount.title')"
:description="t('settings.dangerZone.deleteAccount.description')"
iconBoxClass="bg-danger/10"
hoverClass="hover:bg-danger/5"
>
<template #icon>
<AlertTriangleIcon class="w-5 h-5 text-danger" />
</template>
<template #actions>
<AppButton variant="danger" size="sm" :loading="deletingAccount" :disabled="clearingData" @click="handleDeleteAccount">
<template #icon>
<TrashIcon class="w-4 h-4" />
</template>
{{ t('settings.dangerZone.deleteAccount.button') }}
</AppButton>
</template>
</SettingsRow>
<SettingsRow
:title="t('settings.dangerZone.clearData.title')"
:description="t('settings.dangerZone.clearData.description')"
iconBoxClass="bg-danger/10"
hoverClass="hover:bg-danger/5"
>
<template #icon>
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-danger" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 6h18"/>
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
</svg>
</template>
<template #actions>
<AppButton variant="danger" size="sm" :loading="clearingData" :disabled="deletingAccount" @click="handleClearData">
<template #icon>
<SlidersIcon class="w-4 h-4" />
</template>
{{ t('settings.dangerZone.clearData.button') }}
</AppButton>
</template>
</SettingsRow>
<SettingsNotice tone="warning" class="mx-6 my-4 border-warning/30">
<p class="font-medium text-foreground mb-1">{{ t('settings.dangerZone.warning.title') }}</p>
<p>{{ t('settings.dangerZone.warning.description') }}</p>
</SettingsNotice>
</SettingsSectionCard>
</template>