Skip to content

Commit

Permalink
Merge pull request #28 from SelfDining/development
Browse files Browse the repository at this point in the history
Release v0.1
  • Loading branch information
Yoon-Hae-Min authored Jun 10, 2023
2 parents 35bf659 + cf1e19e commit 78dd88e
Show file tree
Hide file tree
Showing 62 changed files with 10,653 additions and 242 deletions.
7 changes: 6 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
"extends": ["next/core-web-vitals", "prettier"],
"plugins": ["prettier", "unused-imports"],
"rules": {
"prettier/prettier": "warn",
"prettier/prettier": [
"warn",
{
"endOfLine": "auto"
}
],
"no-console": "warn",
"unused-imports/no-unused-imports-ts": "warn"
}
Expand Down
11 changes: 8 additions & 3 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name-template: 'v{version}'
tag-template: 'v{version}'
name-template: 'v$RESOLVED_VERSION 🌈'
tag-template: 'v$RESOLVED_VERSION'
categories:
- title: 'Bug Fixes'
label: '🐛bug'
Expand All @@ -9,4 +9,9 @@ categories:
label: '📝documentation'
- title: 'Chore'
label: '➕chore'

change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
template: |
## Changes
$CHANGES
38 changes: 38 additions & 0 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Chromatic Deployment

on:
pull_request:
paths:
- '**.stories.tsx'
permissions:
contents: read

jobs:
chromatic:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: yarn
- uses: chromaui/action@v1
id: chromatic
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
onlyChanged: true
- name: Add Chromatic URL to PR comment
uses: actions/github-script@v6
with:
script: |
const commentBody = `
Storybook URL: ${{ steps.chromatic.outputs.storybookUrl }}
build URL: ${{ steps.chromatic.outputs.buildUrl }}
`;
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
})
40 changes: 40 additions & 0 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Release Drafter

on:
pull_request:
branches:
- development
# Only following types are handled by the action, but one can default to all as well
types: closed
# pull_request_target event is required for autolabeler to support PRs from forks
# pull_request_target:
# types: [opened, reopened, synchronize]

permissions:
contents: read

jobs:
update_release_draft:
permissions:
# write permission is required to create a github release
contents: write
# write permission is required for autolabeler
# otherwise, read permission is required at least
pull-requests: write
runs-on: ubuntu-latest
steps:
# (Optional) GitHub Enterprise requires GHE_HOST variable set
#- name: Set GHE_HOST
# run: |
# echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV

# Drafts your next Release notes as Pull Requests are merged into "master"
- uses: release-drafter/release-drafter@v5
# (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
# with:
# config-name: my-config.yml
# disable-autolabeler: true
with:
config-file-path: release-drafter.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ yarn-error.log*

# local env files
.env*.local
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# storybook
build-storybook.log
46 changes: 46 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const path = require('path');

module.exports = {
stories: [
'../components/**/*.stories.mdx',
'../components/**/*.stories.@(js|jsx|ts|tsx)'
],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-mdx-gfm'
],
framework: {
name: '@storybook/nextjs',
options: {}
},
docs: {
autodocs: true
},
webpackFinal: (config) => {
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../')
};

// svgr/webpack
const imageRule = config.module?.rules?.find((rule) => {
const test = rule.test;

if (!test) {
return false;
}

return test.test('.svg');
});

imageRule.exclude = /\.svg$/;

config.module?.rules?.push({
test: /\.svg$/,
use: ['@svgr/webpack']
});
return config;
}
};
35 changes: 35 additions & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Global, ThemeProvider } from '@emotion/react';
import { global } from '@/styles/Global';
import theme from '@/styles/theme';
import 'swiper/css';

export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/
}
},
backgrounds: {
default: 'dark',
values: [
{
name: 'dark',
value: '#151517'
// TODO: 색상 코드를 상수로 빼면 해당 색상 hex코드도 상수로 사용하기
}
]
}
};

export const decorators = [
(Story) => (
<>
<ThemeProvider theme={theme}>
<Global styles={global(theme)} />
<Story />
</ThemeProvider>
</>
)
];
53 changes: 53 additions & 0 deletions apis/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import axios, { AxiosError } from 'axios';

export const BASE_URL =
process.env.NODE_ENV === 'production'
? 'https://self-dining.shop/api'
: '/api';

const axiosClient = (() => {
const axiosInstance = axios.create({
baseURL: BASE_URL,
timeout: 3000,
responseType: 'json',
headers: {
'Content-Type': 'application/json'
}
});

axiosInstance.interceptors.response.use(
(response) => {
return response;
},
(error: AxiosError) => {
if (error.code === 'ECONNABORTED') {
alert('서버에 이상이 있습니다.');
}
switch (error.response?.status) {
case 401:
console.warn('401: 인증정보 없음');
break;
case 403:
console.warn('403: 권한 없음');
break;
case 404:
console.warn('404: 대상을 찾지 못함');
break;
case 500:
case 501:
case 502:
case 503:
case 504:
console.warn(`${error.response?.status}: 서버 오류`);
break;
default:
console.error(`${error.response?.status}: unhandled error!`);
break;
}
return Promise.reject(error);
}
);
return axiosInstance;
})();

export default axiosClient;
18 changes: 18 additions & 0 deletions apis/youtube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { YoutubeCategory, YoutubeRecommended } from '@/types/youtube';
import axiosClient from './axios';

export const getRecommendedList = async () => {
const response = await axiosClient.get<YoutubeRecommended[]>(
'/youtube/recommended-list'
);

return response.data;
};

export const getCategoryList = async () => {
const response = await axiosClient.get<YoutubeCategory[]>(
'/youtube/category-list'
);

return response.data;
};
26 changes: 26 additions & 0 deletions components/Carousel/Banner/BannerCarousel.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { StoryFn } from '@storybook/react';
import BannerCarousel, { BannerCarouselProps } from './BannerCarousel';
import { YOUTUBE_BANNER_DUMMY_DATA } from '@/constants/dummyData/youtube';
import { MainContainer } from '@/pages';

const FoodContentCardStory = {
title: 'Component/Banner Carousel',
component: BannerCarousel
};
export default FoodContentCardStory;

const CardTemplate: StoryFn<BannerCarouselProps> = (props) => (
<MainContainer>
<BannerCarousel {...props} />
</MainContainer>
);

/**
* 메인 배너에 보여지는 썸네일 입니다.
*/
export const Default = CardTemplate.bind({});

Default.args = {
contents: YOUTUBE_BANNER_DUMMY_DATA,
isLoading: false
};
77 changes: 77 additions & 0 deletions components/Carousel/Banner/BannerCarousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react';

import FoodContentCard from '@/components/FoodContentCard';

import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, Navigation } from 'swiper';
import 'swiper/css/navigation';
import styled from '@emotion/styled';
import { YoutubeRecommended } from '@/types/youtube';

export type BannerCarouselProps = {
/**Thumbnail 콘텐츠들 */
contents: YoutubeRecommended[] | undefined;
isLoading: boolean;
};

const BannerCarousel = ({ contents, isLoading }: BannerCarouselProps) => {
return (
<BannerContainer>
<Swiper
modules={[Autoplay, Navigation]}
spaceBetween={20}
slidesPerView={2}
centeredSlides={true}
navigation
autoplay={{ delay: 3000, pauseOnMouseEnter: true }}
loop
>
{contents?.map((content) => (
<SwiperSlide
key={`content-${content.id}`}
style={{
transform: 'none'
// z-index를 사용하려면 기존에 있는 transform속성을 초기화 시켜야 사용할수 있음 동시에 사용하면 z-index가 무시됨
}}
>
<ImageContainer
onClick={() => window.open(content.link, '__blank')}
>
<FoodContentCard.Thumbnail
time={content.playTime}
src={content.thumbnailURL}
size="lg"
/>
</ImageContainer>
</SwiperSlide>
))}
</Swiper>
</BannerContainer>
);
};

export default BannerCarousel;

const BannerContainer = styled.div`
min-width: 78.75rem;
.swiper {
overflow: visible;
.swiper-button-next,
.swiper-button-prev {
color: ${({ theme }) => theme.colors.white[50]};
}
}
`;

const ImageContainer = styled.div`
position: relative;
overflow: visible;
aspect-ratio: 16 / 9;
width: 100%;
transition: all 100ms linear;
&:hover {
scale: 1.2;
box-shadow: 0 0 4rem 2rem rgba(0, 0, 0, 0.2);
z-index: 50;
}
`;
Loading

0 comments on commit 78dd88e

Please sign in to comment.