https://www.figma.com/embed?embed_host=notion&url=https%3A%2F%2Fwww.figma.com%2Ffile%2FckYUAr2srqnzskNMzl98ED%2F서비스-Flow%3Ftype%3Dwhiteboard%26node-id%3D165-680%26t%3DZ4vS38qEW6RWKLTK-0

제공된 디자인에 맞춰 수정 진행

Bottom Tab 진행 - 2023년 12월 1일 오후 5:00 (GMT+9)

Untitled

import { View, StyleSheet } from 'react-native';
import Text from '@/components/Text';
import Vote from '@/components/Vote';
import Button from '@/components/Button';
import { theme } from '@/theme/color';
import VoteIcon from '@/assets/icons/vote.svg';
import GhostLegIcon from '@/assets/icons/ghost-leg.svg';
import RouletteIcon from '@/assets/icons/roulette.svg';
function Roulette() {
  return (
    <View>
      <Text>룰렛</Text>
    </View>
  );
}

function GhostLeg() {
  return (
    <View>
      <Text>사다리타기</Text>
    </View>
  );
}

const BottomTab = ({ navigation }) => {
  return (
    <View
      style={{
        flex: 1,
        flexDirection: 'row',
        borderTopColor: '#DBDBDB',
        borderTopWidth: 1,
        maxHeight: 56,
      }}
    >
      <Button
        style={styles.tab}
        color={{ color: '#3F3F3F' }}
        text={
          <View style={{ flexDirection: 'row', alignItems: 'center' }}>
            <VoteIcon width={24} height={24} />
            <Text>투표 만들기</Text>
          </View>
        }
        onPress={() => navigation.push('투표 만들기')}
      />
      <Button
        style={styles.tab}
        color={{ color: '#3F3F3F' }}
        text={
          <View style={{ flexDirection: 'row', alignItems: 'center' }}>
            <GhostLegIcon width={24} height={24} />
            <Text>사다리 타기</Text>
          </View>
        }
      />
      <Button
        style={styles.tab}
        color={{ color: '#3F3F3F' }}
        text={
          <View style={{ flexDirection: 'row', alignItems: 'center' }}>
            <RouletteIcon width={24} height={24} />
            <Text>룰렛 만들기</Text>
          </View>
        }
      />
    </View>
  );
};

const styles = StyleSheet.create({
  tab: {
    flex: 1,
    backgroundColor: theme.background,
    justifyContent: 'center',
  },
});

export default BottomTab;

투표 만들기 수정 - 2023년 12월 4일 오전 11:00 (GMT+9)

헤더 상단

Untitled

// App.js  
        <Stack.Screen
          name="투표 만들기"
          component={Vote}
          options={{
            headerTitleAlign: 'center', // header title center
            headerBackImageSource: // custom header BackImage
              Platform.OS === 'android'
                ? require('@/assets/icons/cancle.png')
                : { uri: 'back', width: 24, height: 24 },
            headerTitleStyle: {
              fontWeight: 'bold',
              color: 'black',
            },
            headerRight: () => (
              <Button
                style={{ backgroundColor: theme.background }}
                color={{ color: theme.main, fontSize: 20 }}
                text="완료"
              />
            ),
          }}
        />

완료 버튼 눌렀을 때 투표가 개설되어야 한다.

하지만 현재는 App.js에서 버튼을 생성해서 핸들링하기 어렵다.

버튼을 핸들링하기 위해서는 해당 컴포넌트안에서 생성해줘야한다.

// components/Vote
export default function Vote({ navigation }) {
	...
  useEffect(() => {
    // header Right 완료 버튼
    navigation.setOptions({
      headerRight: () => (
        <Button
          style={{ backgroundColor: theme.background }}
          color={{ color: theme.main, fontSize: 20 }}
          text="완료"
          onPress={handleSubmitVote}
        />
      ),
    });
  }, [navigation, items]);

	const handleSubmitVote = () => {
    console.log(title);
    console.log(items);
    console.log(getFormatDate(endDate));
    console.log(muilple);
  };
	...
}

Vote 컴포넌트는 App.js에서 Navigation Stack에 등록되어 있어서, navigation prop을 전달받을 수 있다. 전달 받은 navigation에는 다양한 함수가 존재하지만 헤더를 건들기 위해서는 setOptions를 사용할 것이다.

setOptions는 위 stack.screen처럼 navigation에 옵션을 추가할 수 있다. 그래서 이전에 작성해둔 headerRight를 그대로 가져와서 onPress 시 해당하는 함수를 등록해주면 된다.

여기서 주의할 점은 useEffect안에 작성했기 때문에 완료 시 변경된 값들을 의존성 배열에 등록해줘야만 변경된 값을 반영해서 내보낼 수 있다.

옵션 UI - 2023년 12월 4일 오후 5:00 (GMT+9)

Untitled

React-Native에서 기본적으로 제공하는 Switch 컴포넌트가 있다.

// components/Switch
import { Switch as RNSwitch } from 'react-native';
import { theme, voteTheme } from '@/theme/color';
import { useEffect, useState } from 'react';

const Switch = (props) => {
  const { onParentState } = props;
  const [isEnabled, setIsEnabled] = useState(false);
  const toggleSwitch = () => {
    setIsEnabled((previousState) => !previousState);
  };
  useEffect(() => {
    if (onParentState) onParentState(isEnabled);
  }, [isEnabled]);
  return (
    <RNSwitch
      trackColor={{
        false: voteTheme.optionSwitchFalseBackground,
        true: theme.main,
      }}
      thumbColor={voteTheme.optionSwitchTrueText}
      onValueChange={toggleSwitch}
      value={isEnabled}
    />
  );
};

export default Switch;