devjoylee / kicks

P2P Mobile Sneakers Trading Platform ⚡

Home Page:https://kicks-mobile.web.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Logo

Kicks, we're resellers

View Demo Page

Table of Contents

About The Project

It is a shortform trading platform for users who want to buy or resell the sneakers at a reasonable price. I started this project by participating in 'Shortform Video Service Challenge' where I could collaborate with designers and developers.

  • Description : Since there are video services such as "YouTube Shorts" or "Tiktok" that are commonly used, my team decided to clearly determine the service identity rather than having various contents. And my team narrow the scope to the topic of "Second-handed Sneakers Trading", which has a clear fan base and has a strong tendency such as limited edition and resell-tech. We thought this would be perfect service to people who want to see the product condition from various angles.

  • Production Period : 2022.10 - 2022.12

  • Team Members


Jungho Kim(leader)
Designer

Joy Lee
Frontend Developer

Hyeri Shin
Frontend Developer

Sungho Joo
Backend Developer

Choonghwan Kim
Backend Developer

Jaehee Seo
Backend Developer

👉 Go to Our Team Dashboard

👉 Go to Figma


Built With

        


Getting Started

You are able to start the app by typing the following commands in the command line:

git clone https://github.com/devjoylee/kicks.git
npm install
npm start

Main Features

1. Google Authentication

  • OAuth Service
  • Implemented Google sign-in using Firebase's Authentication provider 📝 Read More in my blog
  • Fetched the logged-in user's data (name, profile image..) and saved in sessionStorage to authenticate an user.
// components/Login/GoogleLogin.tsx
import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
import { useNavigate } from 'react-router-dom';
import { auth } from 'server/firebase';
import * as S from './styles';

export const GoogleLogin = () => {
  const navigate = useNavigate();
  const login = async () => {
    try {
      const provider = new GoogleAuthProvider();
      const res = await signInWithPopup(auth, provider);
      if (res) {
        const profile = {
          name: res.user.displayName,
          photoURL: res.user.photoURL
        };
        navigate('/');
        sessionStorage.setItem('kicks-user', JSON.stringify(profile));
      }
    } catch (error) {
      console.log(error);
    }
  };

  return <S.GoogleButton onClick={login}>...</S.GoogleButton>;
};

2. Firebase Database

  • Since the server was closed after the project ended, I refactored the server API code by changing the way to fetch data from the firebase database by myself.
  • Code Preview
// utils/getVideos.ts
import { collection, ... } from 'firebase/firestore';
import { db } from 'server/firebase';
import { IVideoItem } from 'types';

// fetching video list from firebase database
export const getVideos = async () => {
  const q: Query<any> = collection(db, 'videos');
  const querySnapshot: QuerySnapshot<IVideoItem> = await getDocs(q);
  const docs: QueryDocumentSnapshot<IVideoItem>[] = querySnapshot.docs;
  const videos: IVideoItem[] = docs.map(
    (doc: QueryDocumentSnapshot<IVideoItem>) => doc.data()
  );
  return videos;
};

3. Video Swiper

  • Utilized the Swiper React library for the vertical video slider on the main page and the horizontal slider on the search page.

  • Code Preview

// pages/MainPage.tsx
<Swiper direction="vertical">
  {videoList?.map(video => (
    <SwiperSlide key={video.id}>
      <ContentsWrap videoData={video} />
    </SwiperSlide>
  ))}
</Swiper>

4. Chat with a Seller

  • Automatically create a chat room when you click the speech bubble icon in the main video component.

  • Created two util functions, dateConverter and dividedByDate in order to make a section of messages by date.

  • Code Preview

// utils/dateConverter.tsx
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);

export const dateConverter = (date: Date) => {
  const recieved = dayjs(date).format('YYYY-MM-DD');
  const today = dayjs(new Date()).format('YYYY-MM-DD');

  return recieved === today
    ? dayjs(date).format('h:mm A')
    : dayjs(date).fromNow();
};
// utils/dividedByDate.tsx
import { IChat } from 'types';
import dayjs from 'dayjs';

export const dividedByDate = (messages: IChat[]) => {
  const sections: { [key: string]: IChat[] } = {};
  messages.forEach(message => {
    const date = dayjs(message.createAt).format('YYYY. MM. DD');
    if (Array.isArray(sections[date])) {
      sections[date].unshift(message);
    } else {
      sections[date] = [message];
    }
  });
  return Object.entries(sections).reverse();
};

Commit Convention

The commit message is written with the GITMOJI icons in order to make commit messages more intuitive.

Gitmoji Meaning
🎉 Init or begin a project.
🚚 Move or rename resources
Introduce new features
💄 Add the UI and style files
♻️ Refactor code
📝 Add or update documentation
Add a dependency
🐛 Fix a bug
🚀 Deploy stuff

REFERENCE : Gitmoji (http://gitmoji.dev/)

About

P2P Mobile Sneakers Trading Platform ⚡

https://kicks-mobile.web.app/


Languages

Language:TypeScript 99.2%Language:HTML 0.8%