Skip to content

Commit

Permalink
Feat/#60 리뷰 카테고리 선택화면을 추가합니다. (#76)
Browse files Browse the repository at this point in the history
* refactor: 리뷰 탭을 제거한다.

* feat: 태그 스타일을 추가합니다.

* refactor: 카테고리 스타일을 변경합니다.

* feat: 리뷰 카테고리 선택화면을 추가합니다.

* refactor: 주소에 맞게 페이지를 수정합니다.
  • Loading branch information
Zero-1016 authored Oct 5, 2024
1 parent ab3906f commit df1f02f
Show file tree
Hide file tree
Showing 27 changed files with 383 additions and 212 deletions.
36 changes: 14 additions & 22 deletions app/(app)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { Redirect, Tabs } from 'expo-router';
import React from 'react';
import { Text } from 'react-native';

import FireSvg from '@/components/common/icon/fire-svg';
import Typography from '@/components/common/typography';
import type { MainNavigations } from '@/constants';
import { MAIN_NAVIGATIONS } from '@/constants';
import { SITE_URLS } from '@/constants';
import { useSession } from '@/store';
import { useOnboarding } from '@/store/useOnboarding';
import useTabBar from '@/store/useTabBar';
import { flexDirectionRow, flexItemCenter } from '@/styles/common';
import { color } from '@/styles/theme';

const tabBarOptions = {
Expand All @@ -36,15 +36,6 @@ const tabBarOptions = {
/>
),
},
[MAIN_NAVIGATIONS.REVIEW]: {
label: '리뷰',
icon: (color: string) => (
<FireSvg
size={28}
color={color}
/>
),
},
[MAIN_NAVIGATIONS.MY]: {
label: '마이',
icon: (color: string) => (
Expand Down Expand Up @@ -72,7 +63,7 @@ const TabBar = ({ state, descriptors, navigation }: BottomTabBarProps) => {

const isFocused = state.index === index;

if (route.name === 'alarm' || typeof label === 'function') {
if (route.name === 'alarm' || typeof label === 'function' || !tabBarOptions[label]) {
return null;
}

Expand Down Expand Up @@ -103,14 +94,13 @@ const TabBar = ({ state, descriptors, navigation }: BottomTabBarProps) => {
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}>
{tabBarOptions[label].icon(isFocused ? '#000000' : '#cccccc')}
<Typography
variant='Caption2'
style={{ color: isFocused ? '#000000' : '#cccccc' }}>
onLongPress={onLongPress}>
{tabBarOptions[label].icon(isFocused ? color.Common['0'] : '#cccccc')}
<S.TabBarText
$isFocused={isFocused}
variant='Caption2'>
{tabBarOptions[label].label}
</Typography>
</S.TabBarText>
</S.TabBarItem>
);
})}
Expand Down Expand Up @@ -145,26 +135,28 @@ export default function Layout() {
tabBar={(tabBar) => <TabBar {...tabBar} />}>
<Tabs.Screen name={MAIN_NAVIGATIONS.PROJECT} />
<Tabs.Screen name={MAIN_NAVIGATIONS.HOME} />
<Tabs.Screen name={MAIN_NAVIGATIONS.REVIEW} />
<Tabs.Screen name={MAIN_NAVIGATIONS.MY} />
</Tabs>
);
}

const S = {
TabBar: styled.View`
${flexDirectionRow};
position: absolute;
bottom: 0;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 12px 0 24px;
background-color: white;
`,
TabBarItem: styled.TouchableOpacity`
${flexItemCenter};
flex: 1;
gap: 4px;
align-items: center;
justify-content: center;
`,
TabBarText: styled(Typography)<{ $isFocused: boolean }>`
color: ${({ $isFocused }) => ($isFocused ? '#000000' : '#cccccc')};
`,
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Feather } from '@expo/vector-icons';
import { useNavigation, useRouter } from 'expo-router';
import { useLocalSearchParams, useNavigation, useRouter } from 'expo-router';
import { useLayoutEffect } from 'react';
import { Platform, Pressable } from 'react-native';

import { MOCK_PROJECT_DETAIL } from '@/__mock__/project';
import Typography from '@/components/common/typography';
import ProjectDetail from '@/components/project/ProjectDetail';
import { PROJECT_URLS } from '@/constants';
import { color } from '@/styles/theme';

function Page() {
const router = useRouter();
// const { id } = useLocalSearchParams(); 실제 데이터로 올 경우 해당 id를 이용하여 조회
const { id } = useLocalSearchParams<{ id: string }>();
const navigation = useNavigation();
const data = MOCK_PROJECT_DETAIL;

Expand All @@ -37,7 +38,7 @@ function Page() {
),
headerRight: () =>
Platform.OS !== 'web' ? (
<Pressable onPress={() => router.push('/project/create')}>
<Pressable onPress={() => router.push(PROJECT_URLS.PROJECT_CREATE)}>
<Typography
variant='Body1/Normal'
fontWeight='medium'
Expand All @@ -47,9 +48,18 @@ function Page() {
</Pressable>
) : null,
});
}, [navigation]);
}, [data.name, navigation, router]);

return <ProjectDetail data={data} />;
if (!id) {
return null;
}

return (
<ProjectDetail
id={id}
data={data}
/>
);
}

export default Page;
File renamed without changes.
40 changes: 40 additions & 0 deletions app/(app)/project/[id]/review/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Feather } from '@expo/vector-icons';
import { Stack, useRouter } from 'expo-router';
import { Pressable } from 'react-native';

import { PROJECT_URLS, REVIEW_NAVIGATIONS } from '@/constants';
import { color } from '@/styles/theme';

function Layout() {
const router = useRouter();
return (
<Stack
screenOptions={() => ({
headerStyle: { height: 40, backgroundColor: color.Background.Normal },
headerTitleStyle: {
paddingTop: 12,
fontFamily: 'Pretendard-Bold',
},
headerTitleAlign: 'center',
headerShadowVisible: false,
})}>
<Stack.Screen
name={REVIEW_NAVIGATIONS.CREATE}
options={{
title: '나의 설문지',
headerLeft: ({ canGoBack }) => (
<Pressable
onPress={() => (canGoBack ? router.back() : router.push(PROJECT_URLS.PROJECT_HOME))}>
<Feather
name='chevron-left'
size={24}
/>
</Pressable>
),
}}
/>
</Stack>
);
}

export default Layout;
93 changes: 93 additions & 0 deletions app/(app)/project/[id]/review/create.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import styled from '@emotion/native';
import { useCallback, useState } from 'react';

import SolidButton from '@/components/common/button/SolidButton';
import Typography from '@/components/common/typography';
import SelectCategoryChipList from '@/components/questionnaire/SelectCategoryChipList';
import { useTabBarEffect } from '@/hooks';
import { flexDirectionColumn } from '@/styles/common';

const MINIMUM_CATEGORY_COUNT = 5;

function Review() {
useTabBarEffect();
// const { id } = useLocalSearchParams<{ id: string }>();

const [error, setError] = useState<string | null>(null);
const [selectedCategoryList, setSelectedCategoryList] = useState<string[]>([]);

const addCategory = (category: string) => {
if (error) {
setError(null);
}
setSelectedCategoryList([...selectedCategoryList, category]);
};
const removeCategory = (category: string) =>
setSelectedCategoryList(selectedCategoryList.filter((item) => item !== category));

const selectCategory = useCallback(() => {
if (selectedCategoryList.length < MINIMUM_CATEGORY_COUNT) {
setError('5개를 선택해주세요');
return;
}
setError(null);
}, [selectedCategoryList]);

return (
<S.Container>
<S.WrapperBox>
<S.ReviewTitle>
<S.TitleText
variant='Title3'
fontWeight='bold'>
받고 싶은 리뷰의{`\n`}카테고리 5개를 골라주세요
</S.TitleText>
<S.SubTitleText
variant='Label1/Normal'
fontWeight='medium'>
카테고리 별로 설문이 구성돼요
</S.SubTitleText>
</S.ReviewTitle>

<SelectCategoryChipList
item={selectedCategoryList}
addItem={addCategory}
removeItem={removeCategory}
error={error}
/>
</S.WrapperBox>

<SolidButton
onPress={selectCategory}
full>
다음
</SolidButton>
</S.Container>
);
}

const S = {
Container: styled.SafeAreaView`
flex: 1;
gap: 32px;
justify-content: space-between;
padding: 33px 20px 52px;
background: ${({ theme }) => theme.color.Background.Normal};
`,
WrapperBox: styled.View`
${flexDirectionColumn};
gap: 32px;
`,
ReviewTitle: styled.View`
${flexDirectionColumn};
gap: 8px;
`,
TitleText: styled(Typography)`
color: ${({ theme }) => theme.color.Label.Normal};
`,
SubTitleText: styled(Typography)`
color: ${({ theme }) => theme.color.Label.Alternative};
`,
};

export default Review;
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { View } from 'react-native';

import Typography from '@/components/common/typography';

function Review() {
function Page() {
return (
<View>
<Typography>Review</Typography>
<Typography variant='Body1/Normal'>Page</Typography>
</View>
);
}

export default Review;
export default Page;
16 changes: 11 additions & 5 deletions app/(app)/project/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { AntDesign, Feather } from '@expo/vector-icons';
import { Stack, useRouter } from 'expo-router';
import { Platform, Pressable } from 'react-native';
import { Pressable } from 'react-native';

import { PROJECT_NAVIGATIONS } from '@/constants';
import { PROJECT_NAVIGATIONS, PROJECT_URLS } from '@/constants';
import { color } from '@/styles/theme';
import { isMobile } from '@/utils';

import * as S from './style';

Expand Down Expand Up @@ -32,8 +33,8 @@ function Layout() {
size={24}
/>
</Pressable>
{Platform.OS !== 'web' && (
<Pressable onPress={() => router.push('/project/create')}>
{isMobile && (
<Pressable onPress={() => router.push(PROJECT_URLS.PROJECT_CREATE)}>
<AntDesign
name='plus'
size={24}
Expand All @@ -50,7 +51,8 @@ function Layout() {
animation: 'flip',
title: '프로젝트 등록',
headerLeft: ({ canGoBack }) => (
<Pressable onPress={() => (canGoBack ? router.back() : router.push('/project'))}>
<Pressable
onPress={() => (canGoBack ? router.back() : router.push(PROJECT_URLS.PROJECT_HOME))}>
<Feather
name='chevron-left'
size={24}
Expand All @@ -59,6 +61,10 @@ function Layout() {
),
}}
/>
<Stack.Screen
name={PROJECT_NAVIGATIONS.REVIEW}
options={{ headerShown: false }}
/>
</Stack>
);
}
Expand Down
13 changes: 0 additions & 13 deletions app/(app)/project/delete.tsx

This file was deleted.

31 changes: 0 additions & 31 deletions app/(app)/review/_layout.tsx

This file was deleted.

Loading

0 comments on commit df1f02f

Please sign in to comment.