SyntaxSquad/DADProject#9 feat: User info dysplayed in /users/
This commit is contained in:
@@ -2,36 +2,163 @@
|
||||
<div class="profile-page">
|
||||
<h1>My Profile</h1>
|
||||
|
||||
<div v-if="userStore.user">
|
||||
<p><strong>Name:</strong> {{ userStore.user.name }}</p>
|
||||
<p><strong>Email:</strong> {{ userStore.user.email }}</p>
|
||||
<p><strong>Joined:</strong> {{ new Date(userStore.user.created_at).toLocaleString() }}</p>
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="loading">
|
||||
<p>Loading your profile...</p>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<p>Loading... <b> 読み込み中 </b></p>
|
||||
<!-- Error State -->
|
||||
<div v-else-if="error" class="error">
|
||||
<p>Error: {{ error }}</p>
|
||||
<button @click="retry">Retry</button>
|
||||
</div>
|
||||
|
||||
<!-- User Data from Auth Store (preferred) -->
|
||||
<div v-else-if="authStore.currentUser" class="user-info">
|
||||
<div class="info-item">
|
||||
<strong>Name:</strong> {{ authStore.currentUser.name }}
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<strong>Email:</strong> {{ authStore.currentUser.email }}
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<strong>Nickname:</strong> {{ authStore.currentUser.nickname }}
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<strong>Coins Balance:</strong> {{ authStore.currentUser.coins_balance }}
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<strong>Joined:</strong> {{ formatDate(authStore.currentUser.created_at) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No Data State -->
|
||||
<div v-else class="no-data">
|
||||
<p> No user data or not logged in. Please log in to view your profile. </p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { onMounted } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useAPIStore } from '@/stores/api'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const authStore = useAuthStore()
|
||||
const apiStore = useAPIStore()
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(() => {
|
||||
if (!userStore.user) {
|
||||
userStore.fetchUser()
|
||||
const loading = ref(false)
|
||||
const error = ref(null)
|
||||
|
||||
const formatDate = (dateString) => {
|
||||
return new Date(dateString).toLocaleString()
|
||||
}
|
||||
|
||||
const fetchProfile = async () => {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await apiStore.getAuthUser()
|
||||
authStore.currentUser = response.data
|
||||
} catch (err) {
|
||||
error.value = err.response?.data?.message || 'Failed to fetch user profile'
|
||||
|
||||
if (err.response?.status === 401) {
|
||||
await authStore.logout()
|
||||
router.push('/login')
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const retry = () => {
|
||||
fetchProfile()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// Redirect to login if not authenticated
|
||||
if (!authStore.isLoggedIn) {
|
||||
router.push('/login')
|
||||
return
|
||||
}
|
||||
|
||||
// If we already have user data from login, no need to fetch again
|
||||
if (!authStore.currentUser) {
|
||||
await fetchProfile()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style scoped>
|
||||
.profile-page {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
margin: 2rem auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 2rem;
|
||||
color: #333;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
background: #f5f5f5;
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-bottom: 1rem;
|
||||
padding: 0.75rem 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-item strong {
|
||||
min-width: 140px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.loading, .error, .no-data {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #d32f2f;
|
||||
background: #ffebee;
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.no-data {
|
||||
background: #fff3e0;
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-top: 1rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: #1976d2;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #1565c0;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user