Merge branch 'develop' into feature/frontend-gameboard-singleplayer
This commit is contained in:
@@ -87,6 +87,12 @@
|
||||
>
|
||||
Change Password
|
||||
</button>
|
||||
<button
|
||||
:class="['flex-1 p-4 bg-transparent border-none border-b-2 border-transparent cursor-pointer text-sm font-medium text-gray-600 transition-all hover:bg-gray-100 hover:text-black', { 'border-b-black text-black bg-white': activeTab === 'delete' }]"
|
||||
@click="activeTab = 'delete'"
|
||||
>
|
||||
Delete Account
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Profile Information Tab -->
|
||||
@@ -275,11 +281,124 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Delete Account Tab -->
|
||||
<div v-if="activeTab === 'delete'" class="p-8 flex flex-col items-center">
|
||||
<div class="max-w-lg">
|
||||
<div class="border border-red-600 bg-red-50 p-6 mb-6">
|
||||
<div class="flex items-start gap-3">
|
||||
<svg class="w-6 h-6 text-red-600 flex-shrink-0 mt-0.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
|
||||
<line x1="12" y1="9" x2="12" y2="13"/>
|
||||
<line x1="12" y1="17" x2="12.01" y2="17"/>
|
||||
</svg>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-red-900 mb-2">Danger Zone</h3>
|
||||
<p class="text-sm text-red-800 mb-2">
|
||||
Deleting your account is permanent and cannot be undone. This action will:
|
||||
</p>
|
||||
<ul class="text-sm text-red-800 list-disc list-inside space-y-1">
|
||||
<li>Permanently delete all your account data</li>
|
||||
<li>Forfeit your current coin balance of <strong>{{ authStore.currentUser.coins_balance }} coins</strong></li>
|
||||
<li>Remove your access to all games and matches</li>
|
||||
<li>Delete your profile and all associated information</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white border border-gray-300 p-6">
|
||||
<h4 class="text-base font-semibold text-gray-900 mb-4">
|
||||
Are you absolutely sure?
|
||||
</h4>
|
||||
<p class="text-sm text-gray-600 mb-4">
|
||||
To confirm deletion, please type your email address: <strong class="text-black">{{ authStore.currentUser.email }}</strong>
|
||||
</p>
|
||||
|
||||
<input
|
||||
v-model="deleteConfirmEmail"
|
||||
type="text"
|
||||
placeholder="Enter your email to confirm"
|
||||
class="w-full px-3 py-3 border border-gray-300 text-base mb-4 focus:outline-none focus:border-red-600"
|
||||
/>
|
||||
|
||||
<div class="flex gap-4">
|
||||
<button
|
||||
type="button"
|
||||
@click="activeTab = 'info'"
|
||||
class="flex-1 px-6 py-3 border border-gray-300 cursor-pointer text-base font-medium transition-all bg-white text-gray-700 hover:bg-gray-50"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
@click="showDeleteConfirmation = true"
|
||||
:disabled="deleteConfirmEmail !== authStore.currentUser.email"
|
||||
class="flex-1 px-6 py-3 border border-red-600 cursor-pointer text-base font-medium transition-all bg-red-600 text-white hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-red-600"
|
||||
>
|
||||
Delete My Account
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete Confirmation Modal -->
|
||||
<div
|
||||
v-if="showDeleteConfirmation"
|
||||
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50"
|
||||
@click.self="showDeleteConfirmation = false"
|
||||
>
|
||||
<div class="bg-white border border-gray-300 max-w-md w-full shadow-xl">
|
||||
<div class="p-6 border-b border-gray-300">
|
||||
<h3 class="text-xl font-semibold text-gray-900">Final Confirmation</h3>
|
||||
</div>
|
||||
|
||||
<div class="p-6">
|
||||
<div class="flex items-start gap-3 mb-4">
|
||||
<svg class="w-12 h-12 text-red-600 flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<line x1="15" y1="9" x2="9" y2="15"/>
|
||||
<line x1="9" y1="9" x2="15" y2="15"/>
|
||||
</svg>
|
||||
<div>
|
||||
<p class="text-base text-gray-900 font-semibold mb-2">
|
||||
This is your last chance to cancel.
|
||||
</p>
|
||||
<p class="text-sm text-gray-600">
|
||||
Once you click "Yes, Delete My Account", your account and all associated data will be permanently deleted. You will lose your <strong>{{ authStore.currentUser.coins_balance }} coins</strong> forever.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="deletingAccount" class="text-center py-4">
|
||||
<div class="spinner mx-auto mb-3"></div>
|
||||
<p class="text-sm text-gray-600">Deleting your account...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 border-t border-gray-300 flex gap-3">
|
||||
<button
|
||||
@click="showDeleteConfirmation = false"
|
||||
:disabled="deletingAccount"
|
||||
class="flex-1 px-6 py-3 border border-gray-300 cursor-pointer text-base font-medium transition-all bg-white text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
@click="deleteAccount"
|
||||
:disabled="deletingAccount"
|
||||
class="flex-1 px-6 py-3 border border-red-600 cursor-pointer text-base font-medium transition-all bg-red-600 text-white hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
Yes, Delete My Account
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No Data State -->
|
||||
<div v-else class="bg-white border border-gray-300 p-12 text-center shadow-sm max-w-md w-full">
|
||||
<div v-else-if="!authStore.isLoggedIn" class="bg-white border border-gray-300 p-12 text-center shadow-sm max-w-md w-full">
|
||||
<div class="flex flex-col items-center gap-6">
|
||||
<div class="spinner"></div>
|
||||
<p>Redirecting to login...</p>
|
||||
@@ -324,6 +443,11 @@ const updatingPassword = ref(false)
|
||||
const passwordMessage = ref('')
|
||||
const passwordMessageType = ref('')
|
||||
|
||||
// Delete account
|
||||
const deleteConfirmEmail = ref('')
|
||||
const showDeleteConfirmation = ref(false)
|
||||
const deletingAccount = ref(false)
|
||||
|
||||
const formatDate = (dateString) => {
|
||||
const date = new Date(dateString)
|
||||
return date.toLocaleDateString('en-US', {
|
||||
@@ -457,6 +581,27 @@ const handleAvatarUpload = async (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
const deleteAccount = async () => {
|
||||
deletingAccount.value = true
|
||||
|
||||
try {
|
||||
await axios.delete(`${API_BASE_URL}/users/me`)
|
||||
|
||||
// Logout user
|
||||
await authStore.logout()
|
||||
|
||||
// Close modal
|
||||
showDeleteConfirmation.value = false
|
||||
|
||||
// Redirect to home/login
|
||||
router.push('/login')
|
||||
} catch (err) {
|
||||
deletingAccount.value = false
|
||||
showDeleteConfirmation.value = false
|
||||
alert(err.response?.data?.message || 'Failed to delete account')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!authStore.isLoggedIn) {
|
||||
router.push('/login')
|
||||
|
||||
Reference in New Issue
Block a user