Here’s the calendar I’m talking about:
So, basically, I’ve tried to create a following feature: Each day item contains an empty array which will then contain the N number of tasks that are added to that empty array by the purple button below depending on which day is active (The highlighted one), so each day item will have its own array of tasks and I can switch between them to see how many tasks on which day are created. I use Vuex and Vue3 Composition API for this project.
Calendar component:
Calendar.vue
<template>
<div class="wrapper">
<div class="calendar-wrapper">
<div class="calendar-row"
v-for="(day, idx) in dayArr"
:key="idx"
>
<div
id="card"
class="day-card "
:class="{ 'active' : activeDay === idx + 1 }"
@click="switchDay(idx)"
>
<div class="card-info">
<p class="name">{{ day.dayOfWeek }}</p>
<p class="day">
{{ day.currDay }}
</p>
</div>
<div class="dot-wrapper">
<div class="dot-status undone" />
<div class="dot-status undone" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable no-unused-vars */
import { useStore } from 'vuex'
import { onMounted, ref } from 'vue'
export default {
/*=============================================
= Setup =
=============================================*/
setup() {
// ? Turn the remaining days into an array
const fillDayArray = () => {
dayArr.value = Array(daysRemainingThisMonth)
.fill('')
.map((item, index) => {
return {
currDay: moment().add(index, 'day').format('D'),
dayOfWeek: moment().add(index, 'day').format('dddd'),
// Empty array for added tasks:
tasks: []
};
})
}
// Make the clicked day active
const switchDay = (idx) => {
activeDay.value = idx + 1
}
onMounted(() => {
fillDayArray()
})
</script>
Area where tasks are rendered and created:
TaskView.vue
<template>
<div class="task-wrapper">
<p id="task-counter">
Tasks Today: {{ taskArr.length }}
</p>
<div class="task-counter-wrapper">
<!-- ? Render if there are no tasks available: -->
<div
class="empty-msg"
v-if="taskArr.length == 0"
>
<p>Start by adding a New Task!</p>
</div>
<div
class="task-list"
v-for="(task, idx) in taskArr"
:key="idx"
>
<div class="list-item">
<div class="container">
<input class="list-checkbox" type="checkbox">
({{ idx + 1}}) {{ task.name }}
</div>
<div class="item-actions">
<button
class="edit-item btn"
@click="getClickedTask(task)"
>
<img class="icon" src="./Images/editing.png">
</button>
<button
class="delete-item btn"
@click="deleteItem(idx)"
>
<img class="icon" src="./Images/delete.png">
</button>
</div>
</div>
</div>
</div>
<div class="item-card">
<ItemCard />
</div>
<div class="add-task-wrapper">
<button
id="add-task-btn"
@click="addItem()"
>
+ Add a new task
</button>
</div>
</div>
</template>
<script>
/* eslint-disable vue/no-unused-components */
import ItemCard from './ItemCard.vue'
import { useStore } from 'vuex'
// import { computed } from '@vue/reactivity'
export default {
components: {
ItemCard
},
setup() {
const store = useStore()
const taskArr = store.state.taskArr
const getClickedTask = (item) => {
store.state.clickedTask = item
store.state.cardStatus ?
store.state.cardStatus = false
:
store.state.cardStatus = true
};
// ! Delete Item:
const deleteItem = (idx) => {
store.state.taskArr.splice(idx, 1)
}
const addItem = () => {
store.state.taskArr.push(
{
name: 'Empty Task' + Math.random().toString().substring(0, 4),
description: 'No description...'
}
)
}
},
}
</script>
Main area where all other component are rendered:
Main.vue
<template>
<div id="main">
<!-- ! Top Level: -->
<div class="auth">
</div>
<div class="greeting-block">
<button @click="signOutUser">Sign Out</button>
<h1 id="greet-user"> {{ user?.email }}</h1>
</div>
<div class="header-container">
<Header />
<Menu />
</div>
<div class="calendar-display">
<Calendar />
</div>
<div class="task-list">
<TaskView />
</div>
</div>
</template>
<script>
/* eslint-disable vue/no-unused-components */
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
// ? UI Components:
import Header from './Header.vue';
import Calendar from './Calendar.vue';
import Menu from './Menu.vue';
import TaskView from './TaskView.vue';
// ? Auth components:
import Login from '../views/Login.vue'
import Register from '../views/Register.vue'
import Auth from '../Auth.vue'
// ? Firebase:
import { getAuth } from '@firebase/auth'
import { signOut } from '@firebase/auth'
import { useAuthState } from '../firebase'
// ? Router:
import { useRouter } from 'vue-router'
// ? Store:
import { useStore } from 'vuex'
// ? ref():
import { ref } from 'vue'
export default {
components: {
Header,
Calendar,
Menu,
TaskView,
Login,
Register,
Auth
},
name: 'Home',
setup() {
/*=============================================
= Firebase =
=============================================*/
const { user } = useAuthState()
const auth = getAuth()
const router = useRouter()
const signOutUser = async () => {
try {
await signOut(auth)
router.push('/auth')
} catch(e) {
alert(e.message)
}
}
/*===== End of Firebase ======*/
const store = useStore()
const taskArr = store.state.taskArr
}
}
</script>
Vuex store
index.js
state: () => {
return {
cardStatus: false,
clickedTask: null,
taskStatus: null,
dayIsActive: 'active',
cardVisible: true,
// The desired array
taskArr: [ ]
}
},
I think that I probably need to use props, but I really have no idea how do I implement this here. Any ideas would be very appreciated!