Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | <template> <ProfileWidget v-model="showWidget" :tasks="todos" :loading="loading" :error-message="errorMessage" :on-action="onAction" :on-refresh="refresh" /> <div> <h2>{{ t('ui.page.dashboard.root.title') }}</h2> <p>{{ t('ui.page.dashboard.welcome', { displayName: displayName || t('ui.common.guest') }) }}</p> <button @click="logoutAndRedirect">ログアウト</button> <hr /> <h3>外部サービス連携</h3> <button @click="handleGithubLink">GitHubと連携</button> <p v-if="message" class="info">{{ message }}</p> </div> <v-container class="py-6"> <div class="d-flex align-center ga-4 mb-6"> <v-avatar v-if="photoURL" size="56"><img :src="photoURL" alt="" /></v-avatar> <div> <div class="text-h5">{{ displayName }}</div> <div class="text-medium-emphasis">{{ email }}</div> </div> <v-spacer /> <v-chip variant="tonal" color="primary">Role: {{ role }}</v-chip> </div> <v-card> <v-card-title>認証情報</v-card-title> <v-card-text class="d-flex ga-2 flex-wrap"> <v-chip v-for="p in providers" :key="p">{{ p }}</v-chip> <div class="text-caption text-medium-emphasis">UID: {{ uid }}</div> </v-card-text> </v-card> </v-container> <div style="background-color: #7f7f7f; height: 80vh;">ダミー枠</div> </template> <script setup lang="ts"> // region Dependency Injection import {onMounted, ref} from 'vue' import { useI18n } from 'vue-i18n' import {useRouter} from 'vue-router' import {useSchemaLogger} from '@/libs/logger/logger' import {auth} from '@/config/firebase' import {syncWithBackend, useAuth} from '@/composables/useAuth' import {useUserProfile} from '@/composables/useUserProfile' import {useProfileTodos} from '@/composables/useProfileTodos' // endregion Dependency Injection // region interface import ProfileWidget from '@/components/organisms/dashboard/ProfileWidget.vue' // endregion interface // region constants const router = useRouter() const { t } = useI18n() const logger = useSchemaLogger({ module: 'Dashboard' }) const { firebaseUser, signInWithProvider, logout } = useAuth() const { displayName, email, role, uid, providers, photoURL } = useUserProfile() const { loading, errorMessage, todos, refresh, onAction } = useProfileTodos() // endregion constants // region props // endregion props // region variable // endregion variable // region properties const message = ref(''); const showWidget = ref(true) // endregion properties // region emits // endregion emits // region validator // endregion validator // region methods const logoutAndRedirect = async () => { try { await logout() await router.push({name: 'Home'}) } catch (e) { logger.error('ログアウトに失敗しました', e) } }; const handleGithubLink = async () => { message.value = ''; try { // auth.currentUser! await signInWithProvider('github'); message.value = '✅ GitHubと連携しました'; user.value = auth.currentUser; // 再取得 } catch (e: any) { message.value = `⚠️ 連携エラー: ${e.message}`; } }; console.log(JSON.stringify(firebaseUser)) onMounted(() => { syncWithBackend(false).catch(() => {}) refresh() }) // endregion methods // region export // endregion export </script> <style scoped> </style> |