Slide 1

Slide 1 text

フロントのディレクトリ構成 1 フロントのディレクトリ構成 ├─ components/ │ ├─ elements/ │ │ └─ button │ │ └─ Button.tsx │ │ └─ ButtonDisabled.tsx │ └─ layouts/ │ └─ header │ └─ Header.tsx │ └─ sideMenu │ └─ footer ├─ pages/ ├─ features/ │ └─ /messageList │ ├─ api/ │ └─ fetchMessageList.ts │ ├─ states/ │ ├─ constants/ │ ├─ components/ │ ├─ index.tsx │ ├─ MessageListHeader.tsx │ ├─ MessageListTalkBox.tsx │ ├─ MessageListTalkBoxMessage.tsx │ ├─ hooks/ │ └─ types/ │ └─ index.ts ├─ states/ ├─ constants/ ├─ hooks/ ├─ libs/ ├─ styles/ └─ types/ 各ディレクトリの役割 components elements アプリケーション全体で使う共通コンポーネントを置く。 例えばセレクトボックスなど。 具体例

Slide 2

Slide 2 text

フロントのディレクトリ構成 2 /components/elements/select/SelectWithMultiple.tsx export const SelectWithMultiple: React.FC = ({ label, menuItemList, onChange }) => { const [isOpen, setIsOpen] = useState(false); return (
setIsOpen(!isOpen)}>
{label}

プルダウン {menuItemList.map((menuItem, index) => ( {menuItem.checked === true ? onChange(index, !menuItem.checked)}>
: onChange(index, !menuItem.checked)} /> }
{menuItem.label}
))}

Slide 3

Slide 3 text

フロントのディレクトリ構成 3 ); }; layouts アプリケーション全体で使うレイアウトコンポーネントを置く。 例えば、Header やFooter など 具体例 components/layouts/header/LayoutHeader.tsx export const LayoutHeader: React.FC = () => (

スタッフ画像
YOJO 薬局四⾕店
養⽣KANAKO

患者
患者

スタッフ
スタッフ

通知
); pages Next のページコンポーネントを⼊れる。 全体のページを表すもの 具体例

Slide 4

Slide 4 text

フロントのディレクトリ構成 4 この場合はチャットが出来る画⾯なのでChatPage コンポーネント https://www.figma.com/file/1DvdJugCrzT5kkTW9FSSe8/UIdesign?node-id=613%3A786 const ChatPage = styled.div` display: flex; flex-direction: column; height: 100%; `; const Contents = styled.div` display: flex; justify-content: space-between; height: calc(100% - 101px); `; const Home: NextPage = () => ( ); export default Home; features

Slide 5

Slide 5 text

フロントのディレクトリ構成 5 ある特定の機能、ドメインでしか使わないapi へのアクセサや定数、型、hooks 、コンポーネントなど 全てを詰め込む。 状態はstore だとredux と紛らわしく、atom だとrecoil を知らない⼈がみた時にひと⽬で状態管理⽤ のディレクトリだと分かりにくいのでstates という命名にした。 features/components index.tsx から同ディレクトリのコンポーネントを読みこむルールで統⼀ index.tsx にstate をもたせる 命名はパスカルケース 機能名+ コンポーネント名にすることでこの機能に依存していることを表して、すぐに使ってい る場所が分かるようにする。 共通化したいUI パーツはルートディレクトリの/components のelement やlayout に置く メソッドを書く場所 onXXX などのイベントハンドラ系 コンポーネント内に書く formatXXX 、filteredXXX などの整形系 コンポーネントの外に書く 具体例

Slide 6

Slide 6 text

フロントのディレクトリ構成 6 talkRoomCard は↓ の機能を集約

Slide 7

Slide 7 text

フロントのディレクトリ構成 7 states アプリケーション全体で管理したい状態のファイルを置く ログイン情報もログイン機能のstate に書けばいい気がするので、全体のstate はほぼいらないかも しれない。 例:ユーザーの認証情報 import { atom } from 'recoil'

Slide 8

Slide 8 text

フロントのディレクトリ構成 8 export const userState = atom({ key: 'user', default: { id: null, name: '', email: '' } }) constants アプリケーション全体の定数を置く 例:カラーコード、レイアウト系の定数 具体例 const colors = { main: { primary: { light: '#DBEEE3', main: '#7DB894', dark: '#569870', }, secondary: { light: '#838383', main: '#6A6A6A', dark: '#464646', }, }, warning: { positive: { light: '#DBEEE3', main: '#7DB894', dark: '#569870', }, negative: { light: '#FFE1E1', main: '#F39191', dark: '#D36A6A', }, }, sub: { a: { light: '#DFDC92', main: '#B9B552', dark: '#676418', }, b: { light: '#D4DEFF', main: '#839EFF', dark: '#3A51A3', }, }, text: { positive: { light: '#878787', main: '#4D4B4B', dark: '#2B2B2B', }, negative: { light: '#FFE1E1', main: '#F39191', dark: '#D36A6A', }, link: { light: '#DBEEE3', main: '#7DB894',

Slide 9

Slide 9 text

フロントのディレクトリ構成 9 dark: '#569870', }, onDark: { light: '#E3E3E3', main: '#FFFFFF', dark: '#A5A5A5', }, }, background: { primary: { main: '#FFFFFF', dark1: '#F5F5F5', dark2: '#D9D9D9', dark3: '#707070', }, secondary: { main: '#DBEEE3', dark1: '#ACD3BC', dark2: '#7DB894', dark3: '#569870', }, }, }; export default colors; hooks アプリケーション全体で使⽤するcustom Hook を置く場所 ログインの状態を全ページで⾒るhook を全ページのroot で呼びだす 例:useRequireLogin.ts import { useEffect } from 'react' import { useRouter } from 'next/router' import { useFirebaseAuth } from 'util/firebase/client' /** * ログイン状態を確認し、未ログインの場合はログインページへリダイレクトするカスタムフック */ export const useRequireLogin = (): void => { const { user, authInitializing } = useFirebaseAuth() const router = useRouter() useEffect(() => { if (authInitializing) return if (!user) router.push('/') // ログイン画⾯へリダイレクト }, [authInitializing, user, router]) } libs ライブラリのラッパーなど Firebase のクライアントはここに置く

Slide 10

Slide 10 text

フロントのディレクトリ構成 10 styles アプリケーション全体で反映したいスタイルを置く場所 CSS の初期設定 例:global.css * { box-sizing: border-box; } html { margin: 0; padding: 0; } body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; max-width: 50rem; padding: 0.5rem; margin: 0 auto; font-size: 100%; } a { color: inherit; text-decoration: none; } types アプリケーション全体で使う型定義ファイル 独⾃の型定義ファイル、@types モジュールに無いライブラリの型定義ファイルなど Swagger で⾃動出⼒される型やfirestore の型を置いている

Slide 11

Slide 11 text

フロントのディレクトリ構成 11