Skip to content

Commit

Permalink
feat:firebase信箱登入[初版]
Browse files Browse the repository at this point in the history
  • Loading branch information
Shelly committed Oct 9, 2023
1 parent 397b30f commit 79f46db
Show file tree
Hide file tree
Showing 9 changed files with 1,200 additions and 11 deletions.
907 changes: 906 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -12,6 +12,7 @@
"@vueuse/core": "^10.4.1",
"axios": "^1.5.1",
"compressorjs": "^1.2.1",
"firebase": "^10.4.0",
"resize-textarea-vue3": "^1.1.3",
"v-onboarding": "^2.5.2",
"vue": "^3.3.4",
Expand Down
77 changes: 67 additions & 10 deletions src/App.vue
Expand Up @@ -9,14 +9,38 @@
<img src="/vite.svg" alt="" />
<h1 class="text-sm font-bold" id="demo">範例Demo</h1>
</div>

<button
type="button"
class="hover:border-green-600"
@click="asideOpen = !asideOpen"
>
<img src="/src/assets/icon/menu.png" alt="" width="20" />
</button>
<div class="flex items-center">
<button
type="button"
class="bg-yellow-500 text-white p-2"
@click="goToSignIn"
v-if="!isLoggedIn"
>
登入
</button>
<button
type="button"
class="bg-yellow-500 text-white p-2"
@click="handleSignOut"
v-if="isLoggedIn"
>
登出
</button>
<button
type="button"
class="bg-purple-500 text-white p-2"
@click="goToSignUP"
>
註冊
</button>
<button
type="button"
class="hover:border-green-600"
@click="asideOpen = !asideOpen"
>
<img src="/src/assets/icon/menu.png" alt="" width="20" />
</button>
</div>
</div>
</div>
</header>
Expand All @@ -40,8 +64,11 @@
</main>
</template>
<script setup>
import { ref } from 'vue';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { getAuth, onAuthStateChanged, signOut } from 'firebase/auth';
const auth = getAuth();
const router = useRouter();
const asideOpen = ref(true);
const links = ref([
Expand Down Expand Up @@ -73,8 +100,38 @@ const links = ref([
{
text: 'UseMemoize',
to: '/useMemoize'
},
{
text: 'SuccessSign',
to: '/successSign'
}
]);
const goToSignUP = () => {
router.push('/signUp');
};
const goToSignIn = () => {
router.push('/signIn');
};
const isLoggedIn = ref(false);
const handleSignOut = () => {
signOut(auth)
.then(() => {
console.log('已登出');
isLoggedIn.value = false;
router.push('/');
})
.catch(error => {
console.log('登出失敗', error);
});
};
onMounted(() => {
onAuthStateChanged(auth, user => {
user ? (isLoggedIn.value = true) : (isLoggedIn.value = false);
});
});
</script>

<style scoped>
Expand Down
3 changes: 3 additions & 0 deletions src/main.js
Expand Up @@ -3,8 +3,11 @@ import { createVfm } from 'vue-final-modal';
import router from './router';
import ResizeTextarea from 'resize-textarea-vue3';
// import 'vue-final-modal/style.css';
import { setupFirebase } from '@/services/firebase.js';
import './style.css';
import App from './App.vue';

setupFirebase();
const app = createApp(App);

app.use(router).use(createVfm()).use(ResizeTextarea).mount('#app');
39 changes: 39 additions & 0 deletions src/router/index.js
@@ -1,4 +1,5 @@
import { createRouter, createWebHashHistory } from 'vue-router';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
const routes = [
{
path: '/',
Expand Down Expand Up @@ -90,6 +91,22 @@ const routes = [
path: '/useMemoize',
name: 'UseMemoize',
component: () => import('../views/UseMemoize.vue')
},
{
path: '/signUp',
name: 'SignUp',
component: () => import('../views/SignUp.vue')
},
{
path: '/signIn',
name: 'SignIn',
component: () => import('../views/SignIn.vue')
},
{
path: '/successSign',
name: 'SuccessSign',
component: () => import('../views/SuccessSign.vue'),
meta: { requiresAuth: true }
}
];

Expand All @@ -99,4 +116,26 @@ const router = createRouter({
routes
});

const getCurrentUser = () => {
return new Promise((resolve, reject) => {
const removeListener = onAuthStateChanged(
getAuth(),
user => {
removeListener();
resolve(user);
},
reject
);
});
};

router.beforeEach(async (to, from) => {
if (to.meta.requiresAuth && !(await getCurrentUser())) {
return {
path: '/signIn',
query: { redirect: to.fullPath }
};
}
});

export default router;
12 changes: 12 additions & 0 deletions src/services/firebase.js
@@ -0,0 +1,12 @@
import { initializeApp } from 'firebase/app';
const firebaseConfig = {
apiKey: 'AIzaSyASGq7xMYKVVs5_VNO28mMWbD0RTG-tD3o',
authDomain: 'ironman-project-ee339.firebaseapp.com',
projectId: 'ironman-project-ee339',
storageBucket: 'ironman-project-ee339.appspot.com',
messagingSenderId: '434510094271',
appId: '1:434510094271:web:65e6763f416d4fd4df8b0a'
};
export const setupFirebase = () => {
initializeApp(firebaseConfig);
};
82 changes: 82 additions & 0 deletions src/views/SignIn.vue
@@ -0,0 +1,82 @@
<template>
<div class="w-full max-w-xs">
<form class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
<div class="mb-4">
<label class="block text-gray-700 text-sm font-bold mb-2" for="email">
email
</label>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="email"
type="text"
placeholder="email"
v-model="email"
:class="{ 'border-red-500': errMsg }"
/>
</div>
<div class="mb-6">
<label
class="block text-gray-700 text-sm font-bold mb-2"
for="password"
>
Password
</label>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
id="password"
type="password"
placeholder="******************"
v-model="password"
:class="{ 'border-red-500': errMsg }"
/>
</div>

<div class="flex items-center justify-between">
<button
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
type="button"
@click="signIn"
>
登入
</button>
<p class="text-red-500 text-xs italic" v-if="errMsg">
{{ errMsg }}
</p>
</div>
</form>
<p class="text-center text-gray-500 text-xs">
&copy;2020 Acme Corp. All rights reserved.
</p>
</div>
</template>

<script setup>
import { ref } from 'vue';
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
import { useRouter } from 'vue-router';
import { toast } from 'vue3-toastify';
import 'vue3-toastify/dist/index.css';
const router = useRouter();
const email = ref('');
const password = ref('');
const errMsg = ref('');
const auth = getAuth();
const signIn = () => {
signInWithEmailAndPassword(auth, email.value, password.value)
.then(userCredential => {
const user = userCredential.user;
// console.log('登入成功', user);
toast.success('登入成功,即將跳轉頁面');
setTimeout(() => {
router.push('/successSign');
}, 2000);
})
.catch(error => {
console.log('登入失敗', error);
errMsg.value = '登入失敗';
});
};
</script>

<style lang="scss" scoped></style>
83 changes: 83 additions & 0 deletions src/views/SignUp.vue
@@ -0,0 +1,83 @@
<template>
<div class="w-full max-w-xs">
<form class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
<div class="mb-4">
<label class="block text-gray-700 text-sm font-bold mb-2" for="email">
email
</label>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="email"
type="text"
placeholder="email"
v-model="email"
:class="{ 'border-red-500': errMsg }"
/>
</div>
<div class="mb-6">
<label
class="block text-gray-700 text-sm font-bold mb-2"
for="password"
>
Password
</label>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
id="password"
type="password"
placeholder="******************"
v-model="password"
:class="{ 'border-red-500': errMsg }"
/>
</div>
<div class="flex items-center justify-between">
<button
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
type="button"
@click="signUP"
>
註冊
</button>
<p class="text-red-500 text-xs italic" v-if="errMsg">
{{ errMsg }}
</p>
</div>
</form>
<p class="text-center text-gray-500 text-xs">
&copy;2020 Acme Corp. All rights reserved.
</p>
</div>
</template>

<script setup>
import { ref } from 'vue';
import { getAuth, createUserWithEmailAndPassword } from 'firebase/auth';
import { useRouter } from 'vue-router';
import { toast } from 'vue3-toastify';
import 'vue3-toastify/dist/index.css';
const router = useRouter();
const email = ref('');
const password = ref('');
const errMsg = ref('');
const auth = getAuth();
const signUP = () => {
createUserWithEmailAndPassword(auth, email.value, password.value)
.then(userCredential => {
const user = userCredential.user;
// console.log('註冊成功', user);
toast.success('註冊成功,即將跳轉頁面');
setTimeout(() => {
router.push('/successSign');
}, 2000);
})
.catch(error => {
console.log('error', error);
errMsg.value = '註冊失敗';
});
};
</script>

<style lang="scss" scoped></style>
7 changes: 7 additions & 0 deletions src/views/SuccessSign.vue
@@ -0,0 +1,7 @@
<template>
<div>SuccessSign</div>
</template>

<script setup></script>

<style lang="scss" scoped></style>

0 comments on commit 79f46db

Please sign in to comment.