AI를 활용한 무인매장 구현 프로젝트 - 3

섭승이·2024년 6월 27일

캡스톤

목록 보기
3/5

이번 포스트에서는 제가 구현한 알람 페이지와 각종 카테고리에 따른 수량 확인을 할 수 있는 페이지에 대해 설명하겠습니다.

alarmPage.js

const AlarmPage = ({setShowAlarm}) => {
  const [items, setItems] = useState([]);

  const handleGoBack = () => {
    setShowAlarm(false); // 알람 페이지를 닫음
  };

  useEffect(() => {
    requestAlarmGet();
  }, []);

  const requestAlarmGet = async () => {
    try {
      const response = await axios.get('http://localhost:3000/alarms');
      const data = response.data;

 
      setItems(data.alarms);
      console.log(data.alarms);
      //console.log(items);
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <View style={{backgroundColor: '#0247F9', flex: 1}} edges={['top']}>
      <View style={styles.intro_container}>
        <View style={styles.header}>
          <Pressable
            onPress={handleGoBack}
            style={{marginLeft: 20, marginTop: 10}}>
            <Arrow />
          </Pressable>
          <View
            style={{
              flex: 1,
              justifyContent: 'center',
              alignItems: 'center',
              marginRight: 35,
            }}>
            <Text style={[fonts.H3, {color: 'white'}]}>알림</Text>
          </View>
        </View>
      </View>
      <View style={styles.background}>
        <FlatList
          data={items}
          numColumns={1}
          style={{
            width: '100%',
            marginBottom: 20,
            marginTop: 30,
          }}
          renderItem={({item}) => {
            return (
              <View style={styles.alarmItem}>
                <Text
                  style={[fonts.Subtitle2, {marginTop: 10, marginLeft: 22}]}>
                  {item.title}
                </Text>
                <Text style={[fonts.body2, {marginTop: 10, marginLeft: 22}]}>
                  {item.body}
                </Text>
                <Text style={styles.DateText}>{item.date}</Text>
              </View>
            );
          }}
          keyExtractor={(item) => item._id}
          contentContainerStyle={{
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        />
      </View>
    </View>
  );
};

위의 코드가 alarmPage.js 코드입니다.
1. 서버에서 axios.get 메소드를 통해 알람리스트를 받아옵니다.
2. FlatList를 통해 알람리스트를 보여줍니다.

위의 화면이 알람페이지 UI이며 제목, 본문, 날짜 및 시간등이 표시된 모습을 확인할 수 있습니다.


detailPage.js

const DetailPage = ({ setShowDetail, index }) => {
  const [items, setItems] = useState([]);
  const [modalVisible, setModalVisible] = useState(false);

  const handleGoBack = () => {
    setShowDetail(false);
  };

  const handleOrder = () => {
    setModalVisible(true);
  };

  const closeModal = () => {
    setModalVisible(false);
  };

  useEffect(() => {
    requestGet();
  }, []);

  const requestGet = async () => {
    try {
      const response = await axios.get('http://localhost:3000/products');
      const data = response.data;

      const snackItems = data.products.filter(item => item.category === "1");
      const drinkItems = data.products.filter(item => item.category === "2");

      if (index === 0) {
        setItems(snackItems);
      } else if (index === 1) {
        setItems(drinkItems);
      }
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <View style={styles.background}>
      <View
        style={{
          flexDirection: 'row',
          justifyContent: 'space-between',
          paddingHorizontal: 40,
          paddingVertical: 20,
        }}>
        <View style={{ flexDirection: 'row', algnItems: 'center' }}>
          <Text style={fonts.Subtitle1}>과자</Text>
        </View>
        <Text style={fonts.Subtitle1}>이름/수량</Text>
        <Text style={fonts.Subtitle1}>재고관리</Text>
      </View>
      <View
        style={{
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center',
        }}>
        <FlatList
          data={items}
          numColumns={1}
          style={{ width: '100%' }}
          renderItem={({ item, index }) => (
            <View
              style={{
                flexDirection: 'row',
                alignItems: 'center',
                justifyContent: 'space-between',
                marginTop: 12,
                borderBottomWidth: 1,
                borderBottomColor: 'white',
                paddingBottom: 12,
              }}>
              <View style={{ flexDirection: 'row', alignItems: 'center' }}>
              <Image 
                  source={item.category === "1" ? snackImages[index % snackImages.length] : drinkImages[index % drinkImages.length]} 
                  style={styles.image} 
                />
                <View style={{ marginLeft: 40 }}>
                  <Text style={[fonts.Subtitle2, { textAlign: 'center', width: 90 }]}>
                    {item.name}
                  </Text>
                  {item.now_amount > 0 ? (
                    <Text
                      style={[
                        fonts.Subtitle2,
                        { color: 'black' },
                        { textAlign: 'center' },
                      ]}>
                      {item.now_amount}/{item.amount}
                    </Text>
                  ) : (
                    <Text
                      style={[
                        fonts.Subtitle2,
                        { color: 'red' },
                        { textAlign: 'center' },
                      ]}>
                      {item.now_amount}/{item.amount}
                    </Text>
                  )}
                </View>
                <Pressable
                  onPress={handleOrder}
                  style={[styles.orderButton, { marginLeft: 40 }]}>
                  <Text
                    style={[
                      fonts.Subtitle2,
                      { color: 'white', textAlign: 'center' },
                    ]}>
                    주문하기
                  </Text>
                </Pressable>
              </View>
            </View>
          )}
          keyExtractor={(item) => item._id}
          contentContainerStyle={{
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        />
        <Modal
          animationType="slide"
          transparent={true}
          visible={modalVisible}
          onRequestClose={() => {
            closeModal();
          }}>
          {/* 모달 내용 */}
          <View style={styles.centeredView}>
            <View style={styles.modalView}>
              <Text style={styles.modalText}>주문되었습니다!</Text>
              <Pressable
                style={[styles.button, styles.buttonClose]}
                onPress={() => closeModal()}>
                <Text style={styles.textStyle}>닫기</Text>
              </Pressable>
            </View>
          </View>
        </Modal>
        <Pressable onPress={handleGoBack} style={styles.goBackButton}>
          <Text
            style={[fonts.Subtitle2, { color: 'white', textAlign: 'center' }]}>
            돌아가기
          </Text>
        </Pressable>
      </View>
    </View>
  );
};

현재 서버에서 들어오는 데이터의 카테고리가 과자, 음료수밖에 없기 때문에 해당 카테고리에 대해서만 작성하였습니다.

  1. Props 를 통해 받아오는 index를 통해 과자 페이지인지 음료수 페이지인지 확인을 하였습니다.
  2. axios.get 메소드를 통해 서버로부터 상품 데이터를 배열로 받아옵니다.
  3. FlatList와 조건들을 통해 해당 페이지에 맞는 정보를 UI로 보여줍니다.
  4. 주문하기 버튼을 누르면 주문이 완료되었다는 모달을 띄워줍니다.
  5. 돌아가기 버튼을 누르면 index.js 페이지로 돌아갑니다.

위와 같이 상품의 사진, 이름, 현재 수량 및 총 수량, 주문하기 버튼, 돌아가기 버튼을 확인할 수 있습니다.


여기까지가 클라이언트 코드이며 axios 를 통해 서버와 통신하며 알람, 과자 및 수량 정보를 받아옵니다.

매장 상태를 알려주는 아두이노 데이터는 소켓을 통해 실시간으로 받아오며 실시간으로 값이 변동됩니다.

profile
소통하며 성장하는 프론트엔드 개발자 이승섭입니다! 👋

0개의 댓글