新增账号页面

This commit is contained in:
Klein
2023-10-14 02:41:38 +08:00
parent af097c7e45
commit 9fc03edfcb
21 changed files with 315 additions and 6735 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,10 @@
import type { User } from "firebase/auth";
import { db, auth } from "@/firebase";
import { doc, setDoc, getDoc, getDocs, collection } from "firebase/firestore";
import request from '@/utils/request'
export const addUserToUsersCollection = async (user: User) => {
const profile = {
id: user.uid,
name: user.displayName,
avatar: user.photoURL,
created: false,
};
try {
await setDoc(doc(db, "users", user.uid), {
name: user.displayName,
avatar: user.photoURL,
});
profile.created = true;
} catch (error) {
console.error("Error adding document: ", error);
}
return profile;
};
export function getUsers() {
return request({
url: '/account/getUser',
method: 'get',
params: {
}
});
}

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import { useTodoStore } from "@/views/app/todo/todoStore";
const todoStore = useTodoStore();
import { useUserStore } from "@/views/app/user/userStore";
const userStore = useUserStore();
const loading = ref(true);
onMounted(() => {
@@ -10,15 +10,15 @@ onMounted(() => {
});
const searchKey = ref("");
const filterdTodoList = computed(() => {
return todoStore.getTodoList.filter((todo) => {
return todo.title.toLowerCase().includes(searchKey.value.toLowerCase());
const filterdUserList = computed(() => {
return userStore.getUserList.filter((user) => {
return user.title.toLowerCase().includes(searchKey.value.toLowerCase());
});
});
const getLabelColor = (id: string) => {
// Find the label by id from the labels array
const label = todoStore.labels.find((l) => l.id === id);
const label = userStore.labels.find((l) => l.id === id);
// Return the color for that label, or an empty string
return label ? label.color : "";
};
@@ -42,12 +42,12 @@ const getLabelColor = (id: string) => {
v-model="searchKey"
></v-text-field>
<perfect-scrollbar class="todo-list">
<perfect-scrollbar class="user-list">
<transition-group name="fade">
<div v-for="todo in filterdTodoList" :key="todo.id">
<div class="todo-item d-flex align-center pa-5">
<div v-for="user in filterdUserList" :key="user.id">
<div class="user-item d-flex align-center pa-5">
<v-checkbox-btn
v-model="todo.completed"
v-model="user.completed"
color="primary"
class="pe-2"
></v-checkbox-btn>
@@ -60,14 +60,14 @@ const getLabelColor = (id: string) => {
<div class="flex-1 mx-5">
<div
class="font-weight-bold"
:class="todo.completed ? 'text-decoration-line-through' : ''"
:class="user.completed ? 'text-decoration-line-through' : ''"
>
{{ todo.title }}
{{ user.title }}
</div>
<div
:class="todo.completed ? 'text-decoration-line-through' : ''"
:class="user.completed ? 'text-decoration-line-through' : ''"
>
{{ todo.detail }}
{{ user.detail }}
</div>
<div>
<v-chip
@@ -75,7 +75,7 @@ const getLabelColor = (id: string) => {
variant="outlined"
class="mr-1 mt-1"
:color="getLabelColor(tag)"
v-for="tag in todo.tags"
v-for="tag in user.tags"
>
{{ tag }}
</v-chip>
@@ -84,7 +84,7 @@ const getLabelColor = (id: string) => {
<v-btn
icon="mdi-delete-outline"
variant="text"
@click="todoStore.deleteTodoById(todo.id)"
@click="userStore.deleteUserById(user.id)"
></v-btn>
</div>
</div>
@@ -94,10 +94,10 @@ const getLabelColor = (id: string) => {
</template>
<style lang="scss" scoped>
.todo-list {
.user-list {
max-height: 400px;
overflow: scroll;
.todo-item {
.user-item {
transition: all 0.3s;
&:hover {
transition: all 0.3s;

View File

@@ -1,16 +1,16 @@
<!--
* @Component:
* @Component:
* @Maintainer: J.K. Yang
* @Description:
* @Description:
-->
<script setup lang="ts">
import { useCustomizeThemeStore } from "@/stores/customizeTheme";
import ToolbarLanguage from "@/components/toolbar/ToolbarLanguage.vue";
import ToolbarNotifications from "./ToolbarNotifications.vue";
import ToolbarUser from "./ToolbarUser.vue";
import { useTodoStore } from "@/views/app/todo/todoStore";
import { useUserStore } from "@/views/app/user/userStore";
const todoStore = useTodoStore();
const userStore = useUserStore();
const customizeTheme = useCustomizeThemeStore();
const showMobileSearch = ref(false);
</script>
@@ -60,8 +60,8 @@ const showMobileSearch = ref(false);
</v-badge>
</v-btn>
<v-btn to="/apps/todo" class="text-none" stacked>
<v-badge :content="`${todoStore.getTodoList.length} +`" color="error">
<v-btn class="text-none" stacked to="/apps/user">
<v-badge :content="`${userStore.getUserList.length} +`" color="error">
<v-icon>mdi-calendar-check</v-icon>
</v-badge>
</v-btn>

View File

@@ -1,5 +1,5 @@
import unsplashRoutes from "@/views/app/unsplash/UnsplashRoutes";
import todoRoutes from "@/views/app/todo/todoRoutes";
import todoRoutes from "@/views/app/user/userRoutes";
import emailRoutes from "@/views/app/email/emailRoutes";
import chatRoutes from "@/views/app/chat/chatRoutes";
import taskRoutes from "@/views/app/taskcenter/taskRoutes";
@@ -128,7 +128,7 @@ export default [
title: "Todo",
},
component: () =>
import(/* webpackChunkName: "app-todo" */ "@/views/app/todo/TodoApp.vue"),
import(/* webpackChunkName: "app-todo" */ "@/views/app/user/UserApp.vue"),
children: [...todoRoutes],
},
{

View File

@@ -1,12 +1,12 @@
<!--
* @Component:
* @Component:
* @Maintainer: J.K. Yang
* @Description:
* @Description:
-->
<script setup lang="ts">
import { useTodoStore } from "@/views/app/todo/todoStore";
import { useUserStore } from "@/views/app/user/userStore";
import EmailCompose from "./EmailCompose.vue";
const todoStore = useTodoStore();
const todoStore = useUserStore();
</script>
<template>

View File

@@ -1,16 +0,0 @@
<!--
* @Component:
* @Maintainer: J.K. Yang
* @Description:
-->
<script setup lang="ts">
import TodoList from "@/views/app/todo/component/TodoList.vue";
import { useTodoStore } from "@/views/app/todo/todoStore";
const todoStore = useTodoStore();
</script>
<template>
<TodoList :tasks="todoStore.getCompletedTodos" />
</template>
<style scoped lang="scss"></style>

View File

@@ -1,25 +0,0 @@
<!--
* @Component:
* @Maintainer: J.K. Yang
* @Description:
-->
<script setup lang="ts">
import TodoList from "@/views/app/todo/component/TodoList.vue";
import { useTodoStore } from "@/views/app/todo/todoStore";
const todoStore = useTodoStore();
const route = useRoute();
watch(
() => route.params.id,
(id) => {
todoStore.currentLabel = id as string;
}
);
</script>
<template>
<TodoList :tasks="todoStore.getLabelTodos" />
</template>
<style scoped lang="scss"></style>

View File

@@ -1,16 +0,0 @@
<!--
* @Component:
* @Maintainer: J.K. Yang
* @Description:
-->
<script setup lang="ts">
import TodoList from "@/views/app/todo/component/TodoList.vue";
import { useTodoStore } from "@/views/app/todo/todoStore";
const todoStore = useTodoStore();
</script>
<template>
<TodoList :tasks="todoStore.getTodoList" />
</template>
<style scoped lang="scss"></style>

View File

@@ -1,148 +0,0 @@
import { defineStore } from "pinia";
import { Todo } from "./todoTypes";
const todos = [
{
id: 1,
title: "Write a report",
detail: "Draft the quarterly update for the team",
completed: false,
tags: ["work"],
},
{
id: 2,
title: "Attend a meeting",
detail: "Join the conference call with the client",
completed: false,
tags: ["work"],
},
{
id: 3,
title: "Complete a project",
detail: "Finish the coding task before the deadline",
completed: false,
tags: ["work"],
},
{
id: 4,
title: "Take a walk",
detail: "Explore the park and enjoy the nature",
completed: false,
tags: ["relaxation"],
},
{
id: 5,
title: "Meditate",
detail: "Practice mindfulness for 15 minutes",
completed: true,
tags: ["relaxation"],
},
{
id: 6,
title: "Watch a movie",
detail: "Stream a comedy to lighten the mood",
completed: true,
tags: ["relaxation"],
},
{
id: 7,
title: "Buy groceries",
detail: "Stock up on fruits, vegetables, and snacks",
completed: true,
tags: ["shopping"],
},
{
id: 8,
title: "Shop for clothes",
detail: "Look for a new outfit for the weekend",
completed: false,
tags: ["shopping"],
},
{
id: 9,
title: "Order supplies",
detail: "Get some office essentials for the team",
completed: false,
tags: ["shopping", "relaxation"],
},
{
id: 10,
title: "Buy gifts",
detail: "Get presents for friends and family",
completed: false,
tags: ["shopping", "relaxation"],
},
];
export const useTodoStore = defineStore({
id: "todo",
state: () => ({
todList: todos,
currentLabel: "work",
labels: [
{
id: "work",
title: "Work",
color: "orange",
},
{
id: "relaxation",
title: "Relaxation",
color: "green",
},
{
id: "shopping",
title: "Shopping",
color: "blue",
},
],
}),
// persist: {
// enabled: true,
// strategies: [
// {
// storage: localStorage,
// paths: ["todoList"],
// },
// ],
// },
getters: {
// Full list of todos
getTodoList() {
return this.todList.filter((todo: Todo) => !todo.completed);
},
// Completed todos
getCompletedTodos() {
return this.todList.filter((todo: Todo) => todo.completed);
},
// Specific Label todos
getLabelTodos() {
return this.todList.filter(
(todo: Todo) =>
todo.tags && todo.tags.includes(this.currentLabel) && !todo.completed
);
},
},
actions: {
// Add new todo
addNewTodo(todo: Todo) {
todo.id = "_" + Math.random().toString(36).substring(2, 11);
this.todList.push(todo);
},
// update todo
updateTodo(todo: Todo) {
const index = this.todList.findIndex((item: Todo) => item.id === todo.id);
this.todList.splice(index, 1, todo);
},
// Delete todo By Id
deleteTodoById(todoId: string) {
const index = this.todList.findIndex((todo: Todo) => todo.id === todoId);
this.todList.splice(index, 1);
},
},
});

View File

@@ -1,7 +0,0 @@
export interface Todo {
id: string;
title: string;
detail: string;
completed: boolean;
tags: string[];
}

View File

@@ -4,8 +4,29 @@
* @Description:
-->
<script setup lang="ts">
import TodoMenu from "@/views/app/todo/component/TodoMenu.vue";
import TodoCard from "@/views/app/todo/component/TodoCard.vue";
import UserMenu from "@/views/app/user/component/UserMenu.vue";
import UserCard from "@/views/app/user/component/UserCard.vue";
import { useUserStore } from "./userStore";
import {getUsers} from "@/api/userApi";
const userStore = useUserStore();
var labels = new Set();
getUsers().then((res)=>{
let users = res.data
for(let i = 0;i < users.length;i ++){
userStore.addNewUser(users[i])
for(let j = 0;j < users[i].typeList.length;j ++){
labels.add(users[i].typeList[j].type)
}
}
labels.forEach(value => {
userStore.labels.push({
id: String(value),
title: String(value),
color: "black",
})
});
});
</script>
<template>
@@ -14,11 +35,11 @@ import TodoCard from "@/views/app/todo/component/TodoCard.vue";
<!-- Side Bar -->
<!-- ---------------------------------------------- -->
<div class="d-none d-md-block sidebar">
<TodoMenu />
<UserMenu />
</div>
<!-- ---------------------------------------------- -->
<!-- List Todo-->
<!-- List User-->
<!-- ---------------------------------------------- -->
<div class="main">
<router-view v-slot="{ Component }">
@@ -28,7 +49,7 @@ import TodoCard from "@/views/app/todo/component/TodoCard.vue";
</router-view>
</div>
<TodoCard />
<UserCard />
</div>
</template>

View File

@@ -4,11 +4,11 @@
* @Description:
-->
<script setup lang="ts">
import { Todo } from "../todoTypes";
import { useTodoStore } from "../todoStore";
const todoStore = useTodoStore();
import { User } from "../userTypes";
import { useUserStore } from "../userStore";
const userStore = useUserStore();
const dialog = ref(false);
const loadTask = ref<Todo>({
const loadTask = ref<User>({
id: "",
title: "",
detail: "",
@@ -24,9 +24,9 @@ const close = () => {
const save = () => {
if (loadTask.value) {
if (isEdit.value) {
todoStore.updateTodo(loadTask.value);
userStore.updateUser(loadTask.value);
} else {
todoStore.addNewTodo(loadTask.value);
userStore.addNewUser(loadTask.value);
}
}
close();
@@ -72,7 +72,7 @@ const save = () => {
<v-select
v-model="loadTask.tags"
class="px-2 my-3"
:items="todoStore.labels"
:items="userStore.labels"
placeholder="Labels"
item-value="id"
hide-selected

View File

@@ -1,30 +1,30 @@
<!--
* @Component:
* @Component:
* @Maintainer: J.K. Yang
* @Description:
* @Description:
-->
<script setup lang="ts">
import { useTodoStore } from "../todoStore";
import { Todo } from "../todoTypes";
import { useUserStore } from "../userStore";
import { User } from "../userTypes";
const props = defineProps<{
tasks: Todo[];
tasks: User[];
}>();
const todoStore = useTodoStore();
const userStore = useUserStore();
const searchKey = ref("");
const getLabelColor = (id: string) => {
// Find the label by id from the labels array
const label = todoStore.labels.find((l) => l.id === id);
const label = userStore.labels.find((l) => l.id === id);
// Return the color for that label, or an empty string
return label ? label.color : "";
};
// filterdTodoList is a computed value that will filter the todoList based on the searchKey value
const filterdTodoList = computed(() => {
return props.tasks.filter((todo) => {
return todo.title.toLowerCase().includes(searchKey.value.toLowerCase());
// filterdUserList is a computed value that will filter the userList based on the searchKey value
const filterdUserList = computed(() => {
return props.tasks.filter((user) => {
return user.username.toLowerCase().includes(searchKey.value.toLowerCase());
});
});
</script>
@@ -47,15 +47,15 @@ const filterdTodoList = computed(() => {
<!-- ---------------------------------------------- -->
<!-- List -->
<!-- ---------------------------------------------- -->
<perfect-scrollbar class="todo-list">
<perfect-scrollbar class="user-list">
<transition-group name="fade">
<div v-for="todo in filterdTodoList" :key="todo.id">
<div class="todo-item d-flex align-center pa-5">
<v-checkbox-btn
v-model="todo.completed"
<div v-for="user in filterdUserList" :key="user.id">
<div class="user-item d-flex align-center pa-5">
<!--<v-checkbox-btn
v-model="user.completed"
color="primary"
class="pe-2"
></v-checkbox-btn>
></v-checkbox-btn>-->
<v-avatar size="40">
<v-img
src="https://avatars.githubusercontent.com/u/35951244?v=4"
@@ -65,33 +65,32 @@ const filterdTodoList = computed(() => {
<div class="flex-1 mx-5">
<div
class="font-weight-bold"
:class="todo.completed ? 'text-decoration-line-through' : ''"
:class="user.completed ? 'text-decoration-line-through' : ''"
>
{{ todo.title }}
</div>
<div
:class="todo.completed ? 'text-decoration-line-through' : ''"
>
{{ todo.detail }}
{{ user.username }}
</div>
<div>
<v-chip
size="x-small"
variant="outlined"
class="mr-1 mt-1"
:color="getLabelColor(tag)"
v-for="tag in todo.tags"
v-for="tag in user.typeList"
>
{{ tag }}
{{ tag.type }}
</v-chip>
</div>
</div>
<v-btn
<div class="flex-1 mx-5">
{{user.password}}
</div>
<!--<v-btn
size="small"
icon="mdi-delete-outline"
variant="text"
@click="todoStore.deleteTodoById(todo.id)"
></v-btn>
@click="userStore.deleteUserById(user.id)"
></v-btn>-->
</div>
</div>
</transition-group>
@@ -100,10 +99,10 @@ const filterdTodoList = computed(() => {
</template>
<style scoped lang="scss">
.todo-list {
.user-list {
height: 100%;
overflow: scroll;
.todo-item {
.user-item {
transition: all 0.3s;
border-bottom: 1px solid #eee;
&:hover {

View File

@@ -1,11 +1,11 @@
<!--
* @Component:
* @Component:
* @Maintainer: J.K. Yang
* @Description:
* @Description:
-->
<script setup lang="ts">
import { useTodoStore } from "@/views/app/todo/todoStore";
const todoStore = useTodoStore();
import { useUserStore } from "@/views/app/user/userStore";
const userStore = useUserStore();
</script>
<template>
@@ -19,7 +19,7 @@ const todoStore = useTodoStore();
<v-list nav class="mt-2 pa-0">
<v-list-item
prepend-icon="mdi-calendar-check"
to="/apps/todo/tasks"
to="/apps/user/tasks"
active-class="text-primary"
link
title="Tasks"
@@ -27,14 +27,14 @@ const todoStore = useTodoStore();
<template v-slot:append>
<v-badge
color="primary"
:content="todoStore.getTodoList.length"
:content="userStore.getUserList.length"
inline
></v-badge>
</template>
</v-list-item>
<v-list-item
prepend-icon="mdi-check"
to="/apps/todo/completed"
to="/apps/user/completed"
active-class="text-primary"
link
title="Completed"
@@ -42,7 +42,7 @@ const todoStore = useTodoStore();
<template v-slot:append>
<v-badge
color="primary"
:content="todoStore.getCompletedTodos.length"
:content="userStore.getCompletedUsers.length"
inline
></v-badge>
</template>
@@ -51,9 +51,9 @@ const todoStore = useTodoStore();
<div class="pa-1 mt-2 text-overline text-grey">Labels</div>
<v-list nav class="mt-2 pa-0">
<v-list-item
v-for="label in todoStore.labels"
v-for="label in userStore.labels"
active-class="text-primary"
:to="`/apps/todo/label/${label.id}`"
:to="`/apps/user/label/${label.id}`"
link
:title="label.title"
>

View File

@@ -0,0 +1,16 @@
<!--
* @Component:
* @Maintainer: J.K. Yang
* @Description:
-->
<script lang="ts" setup>
import UserList from "@/views/app/user/component/UserList.vue";
import { useUserStore } from "@/views/app/user/userStore";
const userStore = useUserStore();
</script>
<template>
<UserList :tasks="userStore.getCompletedUsers" />
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,25 @@
<!--
* @Component:
* @Maintainer: J.K. Yang
* @Description:
-->
<script lang="ts" setup>
import UserList from "@/views/app/user/component/UserList.vue";
import { useUserStore } from "@/views/app/user/userStore";
const userStore = useUserStore();
const route = useRoute();
watch(
() => route.params.id,
(id) => {
userStore.currentLabel = id as string;
}
);
</script>
<template>
<UserList :tasks="userStore.getLabelUsers" />
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,16 @@
<!--
* @Component:
* @Maintainer: J.K. Yang
* @Description:
-->
<script lang="ts" setup>
import UserList from "@/views/app/user/component/UserList.vue";
import { useUserStore } from "@/views/app/user/userStore";
const userStore = useUserStore();
</script>
<template>
<UserList :tasks="userStore.getUserList" />
</template>
<style lang="scss" scoped></style>

View File

@@ -8,7 +8,7 @@ export default [
name: "apps-todo-tasks",
component: () =>
import(
/* webpackChunkName: "apps-todo-tasks" */ "@/views/app/todo/pages/TasksPage.vue"
/* webpackChunkName: "apps-todo-tasks" */ "@/views/app/user/pages/TasksPage.vue"
),
},
{
@@ -16,7 +16,7 @@ export default [
name: "apps-todo-completed",
component: () =>
import(
/* webpackChunkName: "apps-todo-completed" */ "@/views/app/todo/pages/CompletedPage.vue"
/* webpackChunkName: "apps-todo-completed" */ "@/views/app/user/pages/CompletedPage.vue"
),
},
{
@@ -24,7 +24,7 @@ export default [
name: "apps-todo-label",
component: () =>
import(
/* webpackChunkName: "apps-todo-label" */ "@/views/app/todo/pages/LabelPage.vue"
/* webpackChunkName: "apps-todo-label" */ "@/views/app/user/pages/LabelPage.vue"
),
},
];

View File

@@ -0,0 +1,65 @@
import { defineStore } from "pinia";
import { User } from "./userTypes";
const users = [
];
export const useUserStore = defineStore({
id: "user",
state: () => ({
userList: users,
currentLabel: "sad",
labels: [
],
}),
// persist: {
// enabled: true,
// strategies: [
// {
// storage: localStorage,
// paths: ["userList"],
// },
// ],
// },
getters: {
// Full list of users
getUserList() {
return this.userList.filter((user: User) => !user.completed);
},
// Completed users
getCompletedUsers() {
return this.userList.filter((user: User) => user.completed);
},
// Specific Label users
getLabelUsers() {
return this.userList.filter(
(user: User) =>
user.typeList && user.typeList.some(item => item.type === this.currentLabel) && !user.completed
);
},
},
actions: {
// Add new user
addNewUser(user: User) {
user.uid = "_" + Math.random().toString(36).substring(2, 11);
this.userList.push(user);
},
// update user
updateUser(user: User) {
const index = this.userList.findIndex((item: User) => item.uid === user.uid);
this.userList.splice(index, 1, user);
},
// Delete user By Id
deleteUserById(userId: string) {
const index = this.userList.findIndex((user: User) => user.uid === userId);
this.userList.splice(index, 1);
},
},
});

View File

@@ -0,0 +1,11 @@
export interface User {
uid: string;
title: string;
detail: string;
completed: boolean;
tags: string[];
platform: string;
username: string;
password: string;
typeList: string[];
}