home-page functionality, and some design tweaks
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
<template>
|
||||
<title>Team Management - Reddit for Academic Papers</title>
|
||||
<div
|
||||
class="min-h-screen bg-slate-50 dark:bg-slate-950 p-4 md:p-8 font-sans text-slate-900 dark:text-slate-200 transition-colors duration-300">
|
||||
|
||||
@@ -15,11 +14,11 @@
|
||||
Manage user accounts, roles, and system access permissions
|
||||
</p>
|
||||
</div>
|
||||
<button @click="openCreateModal"
|
||||
class="group relative inline-flex items-center gap-2.5 px-6 py-3 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white font-semibold rounded-xl shadow-lg shadow-blue-500/30 hover:shadow-blue-500/50 transform hover:-translate-y-0.5 active:translate-y-0 transition-all duration-200">
|
||||
<button
|
||||
class="group relative inline-flex items-center gap-2.5 px-6 py-3 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white font-semibold rounded-xl shadow-lg shadow-blue-500/30 hover:shadow-blue-500/50 transform hover:-translate-y-0.5 active:translate-y-0 transition-all duration-200"
|
||||
@click="openCreateModal">
|
||||
<div
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-xl blur opacity-30 group-hover:opacity-50 transition duration-200">
|
||||
</div>
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-xl blur opacity-30 group-hover:opacity-50 transition duration-200" />
|
||||
<svg class="relative w-5 h-5 transition-transform group-hover:rotate-90 duration-300" fill="none"
|
||||
viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
||||
@@ -32,13 +31,12 @@
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div class="relative group">
|
||||
<div
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-2xl blur opacity-0 group-hover:opacity-20 transition duration-300">
|
||||
</div>
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-2xl blur opacity-0 group-hover:opacity-20 transition duration-300" />
|
||||
<div
|
||||
class="relative bg-white dark:bg-slate-900 p-6 rounded-2xl border border-slate-200 dark:border-slate-800 shadow-sm hover:shadow-md transition-all duration-300">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="relative">
|
||||
<div class="absolute -inset-1 bg-blue-500/20 rounded-xl blur"></div>
|
||||
<div class="absolute -inset-1 bg-blue-500/20 rounded-xl blur" />
|
||||
<div
|
||||
class="relative p-3 rounded-xl bg-gradient-to-br from-blue-500 to-blue-600 text-white shadow-lg shadow-blue-500/30">
|
||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -62,13 +60,12 @@
|
||||
|
||||
<div class="relative group">
|
||||
<div
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-emerald-600 to-teal-600 rounded-2xl blur opacity-0 group-hover:opacity-20 transition duration-300">
|
||||
</div>
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-emerald-600 to-teal-600 rounded-2xl blur opacity-0 group-hover:opacity-20 transition duration-300" />
|
||||
<div
|
||||
class="relative bg-white dark:bg-slate-900 p-6 rounded-2xl border border-slate-200 dark:border-slate-800 shadow-sm hover:shadow-md transition-all duration-300">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="relative">
|
||||
<div class="absolute -inset-1 bg-emerald-500/20 rounded-xl blur"></div>
|
||||
<div class="absolute -inset-1 bg-emerald-500/20 rounded-xl blur" />
|
||||
<div
|
||||
class="relative p-3 rounded-xl bg-gradient-to-br from-emerald-500 to-emerald-600 text-white shadow-lg shadow-emerald-500/30">
|
||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -92,13 +89,12 @@
|
||||
|
||||
<div class="relative group">
|
||||
<div
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-purple-600 to-pink-600 rounded-2xl blur opacity-0 group-hover:opacity-20 transition duration-300">
|
||||
</div>
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-purple-600 to-pink-600 rounded-2xl blur opacity-0 group-hover:opacity-20 transition duration-300" />
|
||||
<div
|
||||
class="relative bg-white dark:bg-slate-900 p-6 rounded-2xl border border-slate-200 dark:border-slate-800 shadow-sm hover:shadow-md transition-all duration-300">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="relative">
|
||||
<div class="absolute -inset-1 bg-purple-500/20 rounded-xl blur"></div>
|
||||
<div class="absolute -inset-1 bg-purple-500/20 rounded-xl blur" />
|
||||
<div
|
||||
class="relative p-3 rounded-xl bg-gradient-to-br from-purple-500 to-purple-600 text-white shadow-lg shadow-purple-500/30">
|
||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -124,8 +120,7 @@
|
||||
<!-- Search Bar -->
|
||||
<div class="relative group">
|
||||
<div
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-2xl blur opacity-0 group-hover:opacity-10 transition duration-300">
|
||||
</div>
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-2xl blur opacity-0 group-hover:opacity-10 transition duration-300" />
|
||||
<div
|
||||
class="relative bg-white dark:bg-slate-900 p-1.5 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-800 hover:border-blue-300 dark:hover:border-blue-700/50 transition-all">
|
||||
<div class="flex items-center gap-3 px-4">
|
||||
@@ -142,8 +137,7 @@
|
||||
<!-- Users Table -->
|
||||
<div class="relative group">
|
||||
<div
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-2xl blur opacity-0 group-hover:opacity-5 transition duration-500">
|
||||
</div>
|
||||
class="absolute -inset-0.5 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-2xl blur opacity-0 group-hover:opacity-5 transition duration-500" />
|
||||
<div
|
||||
class="relative bg-white dark:bg-slate-900 rounded-2xl shadow-lg border border-slate-200 dark:border-slate-800 overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
@@ -188,8 +182,7 @@
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="relative">
|
||||
<div
|
||||
class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-full blur opacity-0 group-hover/row:opacity-30 transition duration-300">
|
||||
</div>
|
||||
class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-full blur opacity-0 group-hover/row:opacity-30 transition duration-300" />
|
||||
<div
|
||||
class="relative w-11 h-11 rounded-full bg-gradient-to-br from-blue-500 to-indigo-600 text-white flex items-center justify-center font-bold text-sm shadow-md shadow-blue-500/20">
|
||||
{{ getInitials(user.name) }}
|
||||
@@ -223,16 +216,16 @@
|
||||
class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold shadow-sm border"
|
||||
:class="user.is_active ? 'bg-emerald-100 border-emerald-200 text-emerald-700 dark:bg-emerald-900/30 dark:border-emerald-800 dark:text-emerald-400' : 'bg-red-100 border-red-200 text-red-700 dark:bg-red-900/30 dark:border-red-800 dark:text-red-400'">
|
||||
<span class="w-1.5 h-1.5 rounded-full"
|
||||
:class="user.is_active ? 'bg-emerald-500' : 'bg-red-500'"></span>
|
||||
:class="user.is_active ? 'bg-emerald-500' : 'bg-red-500'" />
|
||||
{{ user.is_active ? 'Active' : 'Suspended' }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="p-6 pr-8 text-right">
|
||||
<div
|
||||
class="flex items-center justify-end gap-2 opacity-0 group-hover/row:opacity-100 transition-opacity duration-200">
|
||||
<button @click.stop="openEditModal(user)"
|
||||
<button
|
||||
class="p-2.5 text-slate-400 hover:text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-lg transition-all transform hover:scale-110 active:scale-95"
|
||||
title="Edit">
|
||||
title="Edit" @click.stop="openEditModal(user)">
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
@@ -240,9 +233,9 @@
|
||||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button @click.stop="confirmDelete(user)"
|
||||
<button
|
||||
class="p-2.5 text-slate-400 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-all transform hover:scale-110 active:scale-95"
|
||||
title="Delete">
|
||||
title="Delete" @click.stop="confirmDelete(user)">
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
@@ -264,8 +257,7 @@
|
||||
<Transition enter-active-class="duration-300 ease-out" enter-from-class="opacity-0" enter-to-class="opacity-100"
|
||||
leave-active-class="duration-200 ease-in" leave-from-class="opacity-100" leave-to-class="opacity-0">
|
||||
<div v-if="showModal" class="fixed inset-0 z-[100] overflow-y-auto" role="dialog" aria-modal="true">
|
||||
<div class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm transition-opacity" @click="closeModal">
|
||||
</div>
|
||||
<div class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm transition-opacity" @click="closeModal" />
|
||||
<div class="flex min-h-full items-center justify-center p-4">
|
||||
<Transition enter-active-class="duration-300 ease-out"
|
||||
enter-from-class="opacity-0 scale-95 translate-y-4"
|
||||
@@ -274,8 +266,7 @@
|
||||
leave-to-class="opacity-0 scale-95 translate-y-4">
|
||||
<div class="relative w-full max-w-2xl">
|
||||
<div
|
||||
class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-3xl blur opacity-20">
|
||||
</div>
|
||||
class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-3xl blur opacity-20" />
|
||||
<div
|
||||
class="relative overflow-hidden rounded-2xl bg-white dark:bg-slate-900 shadow-2xl border border-slate-200 dark:border-slate-800">
|
||||
|
||||
@@ -283,14 +274,13 @@
|
||||
class="relative bg-gradient-to-r from-slate-50 to-slate-100/50 dark:from-slate-800/50 dark:to-slate-800/30 px-8 py-6 border-b border-slate-200 dark:border-slate-800 flex justify-between items-center">
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-1.5 h-8 bg-gradient-to-b from-blue-600 to-indigo-600 rounded-full">
|
||||
</div>
|
||||
class="w-1.5 h-8 bg-gradient-to-b from-blue-600 to-indigo-600 rounded-full" />
|
||||
<h3 class="text-xl font-bold text-slate-900 dark:text-white">{{ isEditing ?
|
||||
'Edit User Details' : 'Create New User' }}</h3>
|
||||
</div>
|
||||
<button @click="closeModal"
|
||||
class="p-2 text-slate-400 hover:text-slate-600 dark:hover:text-slate-300"><svg
|
||||
class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<button class="p-2 text-slate-400 hover:text-slate-600 dark:hover:text-slate-300"
|
||||
@click="closeModal"><svg class="w-5 h-5" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12" />
|
||||
</svg></button>
|
||||
@@ -355,8 +345,7 @@
|
||||
<input v-model="formData.is_active" type="checkbox"
|
||||
class="sr-only peer">
|
||||
<div
|
||||
class="w-11 h-6 bg-slate-200 rounded-full peer peer-checked:bg-blue-600 dark:bg-slate-700 peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all">
|
||||
</div>
|
||||
class="w-11 h-6 bg-slate-200 rounded-full peer peer-checked:bg-blue-600 dark:bg-slate-700 peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all" />
|
||||
</div>
|
||||
<span class="text-sm font-semibold transition-colors"
|
||||
:class="formData.is_active ? 'text-slate-900 dark:text-white' : 'text-slate-500'">{{
|
||||
@@ -366,8 +355,9 @@
|
||||
</div>
|
||||
|
||||
<div v-if="isEditing" class="pt-2 border-t border-slate-100 dark:border-slate-800">
|
||||
<button type="button" @click="sendPasswordRecovery"
|
||||
class="text-sm text-red-500 hover:text-red-600 font-semibold flex items-center gap-2">
|
||||
<button type="button"
|
||||
class="text-sm text-red-500 hover:text-red-600 font-semibold flex items-center gap-2"
|
||||
@click="sendPasswordRecovery">
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
|
||||
@@ -379,11 +369,13 @@
|
||||
|
||||
<div
|
||||
class="bg-gradient-to-r from-slate-50 to-slate-100/50 dark:from-slate-800/50 dark:to-slate-800/30 px-8 py-6 border-t border-slate-200 dark:border-slate-800 flex flex-row-reverse gap-3">
|
||||
<button @click="handleSubmit"
|
||||
class="px-8 py-3 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-xl shadow-lg transition-all">{{
|
||||
<button
|
||||
class="px-8 py-3 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-xl shadow-lg transition-all"
|
||||
@click="handleSubmit">{{
|
||||
isEditing ? 'Save Changes' : 'Create Account' }}</button>
|
||||
<button @click="closeModal"
|
||||
class="px-8 py-3 bg-white dark:bg-slate-800 border-2 border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 font-semibold rounded-xl transition-all">Cancel</button>
|
||||
<button
|
||||
class="px-8 py-3 bg-white dark:bg-slate-800 border-2 border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 font-semibold rounded-xl transition-all"
|
||||
@click="closeModal">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -397,7 +389,7 @@
|
||||
leave-active-class="duration-200 ease-in" leave-from-class="opacity-100" leave-to-class="opacity-0">
|
||||
<div v-if="showDetailsModal" class="fixed inset-0 z-[100] overflow-y-auto" role="dialog" aria-modal="true">
|
||||
<div class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm transition-opacity"
|
||||
@click="closeDetailsModal"></div>
|
||||
@click="closeDetailsModal" />
|
||||
<div class="flex min-h-full items-center justify-center p-4">
|
||||
<Transition enter-active-class="duration-300 ease-out"
|
||||
enter-from-class="opacity-0 scale-95 translate-y-4"
|
||||
@@ -427,9 +419,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button @click="closeDetailsModal"
|
||||
class="p-2 text-slate-400 hover:text-slate-600 dark:hover:text-slate-300"><svg
|
||||
class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<button class="p-2 text-slate-400 hover:text-slate-600 dark:hover:text-slate-300"
|
||||
@click="closeDetailsModal"><svg class="w-5 h-5" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12" />
|
||||
</svg></button>
|
||||
@@ -470,7 +462,7 @@
|
||||
class="px-2.5 py-1 rounded-md text-xs font-bold uppercase tracking-wide bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300">{{
|
||||
item.action.replace('_', ' ') }}</span>
|
||||
<span class="text-xs text-slate-400 font-medium">{{ item.target_type
|
||||
}} #{{ item.target_id }}</span>
|
||||
}} #{{ item.target_id }}</span>
|
||||
</div>
|
||||
<p class="text-sm text-slate-700 dark:text-slate-300 leading-relaxed">{{
|
||||
item.details }}</p>
|
||||
@@ -482,8 +474,9 @@
|
||||
|
||||
<div
|
||||
class="flex-none bg-gradient-to-r from-slate-50 to-slate-100/50 dark:from-slate-800/50 dark:to-slate-800/30 px-8 py-4 border-t border-slate-200 dark:border-slate-800">
|
||||
<button @click="closeDetailsModal"
|
||||
class="w-full px-6 py-3 bg-white dark:bg-slate-800 border-2 border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 font-semibold rounded-xl transition-all">Close</button>
|
||||
<button
|
||||
class="w-full px-6 py-3 bg-white dark:bg-slate-800 border-2 border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 font-semibold rounded-xl transition-all"
|
||||
@click="closeDetailsModal">Close</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user