Giter VIP home page Giter VIP logo

coach-finder's Introduction

Coach Finder

Go outside and learn new stuff!

Post pandemic, outdoor activities are getting back on track and Coach Finder, a Vue.js webapp, allows learners to find their ideal coaches to learn new sports and coaches to advertise themselves! With this app, you can:

As a student
  • Browse all coaching offers or use filter to browse specific postings
  • Contact a coach by leaving a message and your email
As a coach
  • Register as a coach and post what you want to teach and provide student level requirements and a detailed description
  • Check student requests and get his/her email for further discussion

Demo

Here is a working live demo : Coach Finder

Walkthrough

In this section, I will walk through all the important Vue.js skills I learned from this amazing online course.

Project Structure

project structure

  • pages folder - Holds components that are loaded as pages through routing e.g. Login/Signup components
  • components folder - Other components that are not loaded throgh routing, e.g. Base UI components
  • store folder - Vuex modules. Split into separate modules to make each file cleaner

Basic Usage

Used throughout the whole project

  • Interpolations - {{ expression }}
  • Directives - :show, v-if, v-else, v-model โ€ฆ
  • Passing data between child and parent components - props and custom events
  • Slots (source: src/components/ui/BaseButton.vue)
<template>
  <button v-if="!link" :class="mode">
    <slot></slot>
  </button>
  <router-link v-else :to="to" :class="mode">
    <slot></slot>
  </router-link>
</template>

Routing

routing

  • Created routing logic using the createRouter function from vue-router module.
  • Used nested route for contacting a specific coach

Managing Global States

Split into three types of modules and using namespace. (source: src/store/index.js)

import coachesModule from './modules/coaches/index.js'
//...
const store = createStore({
  modules: {
    coaches: coachesModule,
    //...
  },
});

Each type of module has an entry index.js that stores states and imports mutations, actions and getters

import mutations from './mutations.js';
import actions from './actions.js';
import getters from './getters.js';

export default { state() {return {//...}; }, mutations, actions, getters }

Used getters to hide state accessing logic. (source: src/store/modules/coaches/getter.js)

  isCoach(_, getters, _2, rootGetters) {
    const coaches = getters.coaches;
    const userId = rootGetters.userId;
    return coaches.some(coach => coach.id === userId);
  },

Used mutations to modify states. (source: src/store/modules/requests/mutations.js)

  addRequest(state, payload) {
    state.requests.push(payload);
  },

Used actions for asynchronous logics and committing mutations. (source: src/store/modules/requests/actions.js)

async contactCoach(context, payload) {
    //...
    const response = await fetch(someURL, {
      method: 'POST',
      body: JSON.stringify(newRequest)
    });
    //...
    context.commit('addRequest', newRequest);
  },

Communicating With Backend

  • Set up a Firebase database
  • Used javascript built-in fetch() function to send http requests
const response = await fetch(url, {
        method: 'PUT',
        body: JSON.stringify(coachData)
      }
    );

Adding Animations and Transitions

(source: src/components/ui/BaseDialog.vue)

<transition name="dialog">
    <dialog open v-if="show">
      //...
    </dialog>
</transition>
.dialog-enter-from,
.dialog-leave-to {
  opacity: 0;
  transform: scale(0.8);
}
.dialog-enter-active {
  transition: all 0.3s ease-out;
}
.dialog-leave-active {
  transition: all 0.3s ease-in;
}
.dialog-enter-to,
.dialog-leave-from {
  opacity: 1;
  transform: scale(1);
}

Authentication

  • Using Firebase authentication
  • Lock resources based on user logged in or not
  • Add navigation guards (source: src/router.js)
router.beforeEach(function (to, _, next) {
  if (to.meta.requiresAuth && !store.getters.isAuthenticated) {
    next('/auth');
  } else if (to.meta.requiresUnauth && store.getters.isAuthenticated) {
    next('/coaches');
  } else {
    next();
  }
});

Optimization

Add lazy loading (source: src/main.js)

const BaseDialog = defineAsyncComponent(() => 
    import('./components/ui/BaseDialog.vue'));

Setup

Install the dependencies and devDependencies and run in development environment.

npm install
npm run serve

coach-finder's People

Contributors

kaichiehuang avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.