[프로젝트 회고] 국민은행 액티브 시니어 온보딩 페이지

AnSuebin·2022년 11월 9일
2
post-thumbnail

국민은행 액티브 시니어 온보딩 페이지 바로가기
GitHub 바로가기

목차
01. 챌린지 시작
02. 프로젝트 방향성
03. 개발조건
04. 코드 설명
05. 프로젝트 기획기간 인터렉티브 버튼 모음 제작
06. 마치며

🏁 01. 챌린지 시작

기획자, 디자이너와 협업하는 것에 관심이 많아, 넘블이 주최한 '액티브 시니어를 위한 금융 앱 온보딩 페이지 제작 챌린지'에 참여했습니다.
기획자 2명, 디자이녀 1명, 프론트엔드 개발자인 저 4명이 한팀이 되어 프로젝트를 진행하였고, 액티브 시니어를 타겟으로 금융 앱 온보딩 페이지를 제작하라는 미션을 받았습니다.
기획자가 보는 웹, 디자이너가 보는 웹이 저와 어떤 차이가 있는지 궁금했고, 그런 다른 시각에서 시너지 효과가 날 수 있을 것이란 기대로 참여하게 되었습니다.

챌린지에 들어가기 앞서 이번 프로젝트에서 얻어가려 했던 부분은 협업이었습니다.
개발의 관점에서는 누가 보더라도 최대한 깔끔하게 이해할 수 있는 코드를 작성해보는 것,
팀원들과는 공유가 어렵지 않도록 하고, 다른 관점을 이해하고 그것이 프로젝트에 잘 담아지도록 노력하였습니다.

👥 02. 프로젝트 방향성

  • 액티브 시니어들이 금융앱을 보다 편하게 사용할 수 있도록 하는 것이 가장 큰 목표였습니다.
  • 이에 따라 컨셉을 인터렉티브 앱으로 정하여, 사용자들이 간단한 동작을 직접 경험해보며 앱에 대한 이해 높일 수 있게 제작하는 것을 목표로 하였습니다.
  • 또한 50대 이상의 사용률이 가장 높지만, 시니어 세대를 위한 기능이 아쉬운 국민은행 앱을 선정하여, 개선해보고자 하였습니다.

🖥️ 03. 개발조건

디자이너, 기획자와 함께 프로젝트를 하는 만큼,
기획과 디자인이 잘 보일 수 있는 방향으로 최대한 노력하였고, 공유가 원활할 수 있는 환경을 제공하고자 하였습니다.

  • React Framework를 사용
  • Styled Component 사용
  • 인터렉티브 기능에 있어서 라이브러리의 사용을 최대한 지양하고, 자체적으로 기능들을 구현
  • Github Action, Github Pages를 활용하여 팀원과 개발 과정 공유

⚙️ 04. 코드 설명

코드를 작성에서 가장 중요하게 고려한 점은 다른 사람이 제 코드를 봤을 때 쉽게 이해할 수 있도록 작성해 보는 것 이었습니다.

1) 파일 구조

  • 파일 구조를 assets / components / data / font / pages / utils로 구분하였습니다.
  • component들 중 함께 사용하는 것은 Components에 올리고, 그 외의 컴포넌트는 각 페이지에서만 사용하는 컴포넌트는 pages에서 따로 component 폴더에 분리해 두었습니다.

2) 페이지별 설명

1page. 안전성

애니메이션과 아이콘을 활용하여, 사용자의 반응 유도
작은 요소들이 많은 페이지였습니다. 각각을 디자이너가 요청한 위치, 시간대에 넣는 작업을 하며, 현실과 타협했던 디자인에서 벗어나 꼼꼼하게 페이지를 구현하는 경험을 할 수 있었습니다.
또한 lottie, 애니메이션등 시각적으로 새로운 형태를 구현해볼 수 있었습니다.

2page. 편리성

영상 및 애니메이션을 활용하여, 사용자가 직접 영상통화를 체험하는 듯한 경험 제공
영상, 대화 글귀, 버튼 등 컴포넌트들이 보여지는 타이밍을 맞추는 작업을 중점적으로 하였습니다.
추후, 영상의 로딩 시간을 단축시키고 성능을 향상시키고 싶습니다.

3page. 접근성

기능별, 페이지별 자동으로 넘어가는 것이 많은 페이지
최대한 자연스럽고 부드럽게 보여지도록 표현

편리성과 마찬가지로 자동으로 넘어가고 보여지는 페이지가 많은 페이지였습니다.
깃 페이지스를 활용하여 소통하고 수정하는 작업을 진행하며 디자이너와 더 깊이있는 협업을 진행 할 수 있던 페이지였습니다.

4page. 전문성

애니메이션과 아이콘을 활용하여, 사용자의 반응 유도
앞의 페이지들을 제작하며 수월하게 작업할 수 있었습니다. 이 부분도 마찬가지로 자동 스크롤이 올라가는 시간을 디자이너와 협업하며 제작할 수 있는 페이지였습니다.

5page. 경제성

애니메이션과 아이콘을 활용하여, 사용자의 반응 유도
제작 막바지에 전체적인 수정이 진행되었던 페이지입니다. 많이 남지 않은 시간으로 팀원들과 우선순위를 정하며 제작 하였습니다. 완성도에 대한 동료의 입장차와 이를 조율하는 과정을 경험할 수 있던 페이지였습니다.

6page. 직관성

스위치 아이콘을 제작하여, 사용자의 기능 인지 유도
스위치에 선택 시 안정적이지 못한 형태와, 아이콘이 있을 때 스위치가 안먹히는 에러 등 문제를 가장 많이 만났던 페이지입니다.
처음에는 완전한 기능의 스위치을 제작하였지만, 온보딩 페이지에 스위치를 켰다 컸다 하는 것이 유저 경험으로 좋지 않다는 판단되어, 스위치 클릭시 완료로 넘어가는 형식으로 다시 구현하였습니다.

3) 구현 포인트

3-1) 페이지가 바뀔 때, 부드럽게 그리고 자연스럽게

  • 제작 당시 협의한 결과 자연스러우면서, 부드럽게 보이길 원했습니다.
  • 따라서 전체 페이지에 기본 형태에 animation을 입히고, 그 외 다른 요소에도 animation을 적극 활용하여 최대한 자연스러운 형태로 구현하고자 하였습니다.
  • 페이지 도입 시, 메인 이미지에 입힌 animation 효과
//-- 애니메이션 --//
const fadeIn = keyframes`
from {
  opacity: 0;
}
to {
  opacity: 1;
  transform: translateY(0);
}
`;
//-- 스타일 --//
const MainImageContainer = styled.div`
  animation-duration: 0.75s;
  animation-timing-function: ease-in-out;
  animation-name: ${fadeIn};
  animation-fill-mode: forwards;
`;
  • 페이지 내 클릭 시, 넘어갈 때 animation 효과
//-- 애니메이션 --//
const opacity = keyframes`
from {
  opacity: 0;
}
to {
  opacity: 1;
}
`;
//-- 스타일 --//
const PortfolioContainer = styled.div`
  position: absolute;

  top: 32px;
  left: 50%;
  transform: translateX(-50%);

  width: 312px;
  height: 296px;

  overflow: hidden;
  z-index: 1;
  div {
    display: flex;
    justify-content: center;
    margin-top: 20px;
    overflow: hidden;
  }

  animation-duration: 0.75s;
  animation-timing-function: ease-in-out;
  animation-name: ${opacity};
  animation-fill-mode: backwards;
`;

3-2) 로티 사용하기

  • 시각적인 효과를 극대화 하기 위해, 버튼 유도, 성공 창 등 즉각적인 반응이 필요한 부분에서 로티를 사용하였습니다.
  • 로티 실행 라이브러리는 lottie-react를 사용하였습니다.
  • 로티를 활용한 클릭 유도 컴포넌트
// CSS
import styled from 'styled-components';
// 로티 에니메이션
import Lottie from 'lottie-react';
import click from '../assets/lottie/click.json';

const ClickIcon = styled.div`
  position: absolute;
  width: 200px;
  left: 50%;
  top: ${(props) => props.top};
  transform: ${(props) => props.transform};
  z-index: 5;
`;

const Click = ({ onClick, top, transform }) => {
  return (
    <>
      <ClickIcon top={top} transform={transform}>
        <Lottie
          animationData={click}
          loop={true}
          style={{ width: 200 }}
          onClick={onClick}
        />
      </ClickIcon>
    </>
  );
};

export default Click;

3-3) 말하면 입력되는 것 같이 느끼게 해주는 typingText 기능 구현

- setInterval을 통해서 지정된 시간마다 txt에서 값을 받아와, 한 글자씩 넣어주는 로직을 구현하였습니다.
const Typing = styled.p`
  font-family: 'Bold';
  font-size: 21px;
  line-height: 26px;
  letter-spacing: -0.02em;
  color: #222222;
`;

const TypingText = () => {
  const txt = '노후연금 추천해줘';
  const [isTypingTime, setIsTypingTime] = useState(false);
  const [Text, setText] = useState('');
  const [Count, setCount] = useState(0);

  // 타이핑 시작 타이밍
  useEffect(() => {
    const timeout = setTimeout(() => {
      setIsTypingTime(true);
    }, 900);
    return () => {
      clearTimeout(timeout);
    };
  }, [isTypingTime]);

  // 타이핑 속도
  useEffect(() => {
    if (isTypingTime) {
      const interval = setInterval(() => {
        setText(Text + txt[Count]);
        setCount(Count + 1);
      }, 260);
      if (Count === txt.length) {
        clearInterval(interval);
      }
      return () => clearInterval(interval);
    }
  });

  return <>{isTypingTime === true && <Typing>{Text}</Typing>}</>;
};

3-4) 스위치 기능 제작, 페이지에 맞게 로직 수정

  • 기존에는 스위치를 input 체크박스 태그를 베이스로 제작해, 체크되면 변화되는 형태로 구현하였습니다.
const ReactSwitchButton = styled.span`
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 45px;
  height: 45px;
  border-radius: 45px;
  transition: 0.2s;
  background: #fff;
  box-shadow: 0 0 2px 0 rgba(10, 10, 10, 0.29);
`;
const ReactSwitchLabel = styled.label`
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100px;
  height: 50px;
  background: grey;
  border-radius: 100px;
  position: relative;
  transition: background-color 0.2s;
  cursor: pointer;
  &:active ${ReactSwitchButton} {
    width: 60px;
  }
`;

const ReactSwitchCheckbox = styled.input`
  height: 0;
  width: 0;
  visibility: hidden;
  &:checked + ${ReactSwitchLabel} {
    background: rgb(254, 244, 148, 0.777);
    ${ReactSwitchButton} {
      left: calc(100% - 2px);
      transform: translateX(-100%);
    }
  }
`;

const Switch = () => {
  const [value, setValue] = useState(false);
  return (
    <ButtonContainer>
      <ReactSwitchCheckbox
        id={`react-switch-new`}
        type="checkbox"
        checked={value}
        onChange={() => {
          setValue(!value);
        }}
      />
      <ReactSwitchLabel htmlFor={`react-switch-new`}>
        <ReactSwitchButton />
      </ReactSwitchLabel>
    </ButtonContainer>
  );
};
  • 그러나 클릭 유도 애니메이션이 버튼을 가리고, 잘 못 눌릴 경우 잘못된 경로로 넘어가는 이슈가 발생하여, 스위치의 기능 보다는 클릭 시 페이지가 전환되는 형태로 변경하였습니다.
const ButtonSlide = keyframes`
  from {
  }
  to {
    left: calc(100%);
    transform: translateX(-100%);
    background-color: #f5bf41;
  }
`;

const SwitchButton = styled.span`
  content: '';
  position: absolute;
  left: 2px;

  width: 24px;
  height: 24px;
  border-radius: 45px;
  background: #888e98;
  box-shadow: 5px 5px 12px rgba(144, 145, 146, 0.2);

  ${(props) =>
    props.isChecked &&
    css`
      animation-duration: 0.2s;
      animation-timing-function: ease-in;
      animation-name: ${ButtonSlide};
      animation-fill-mode: forwards;
    `}
`;

const SwitchLabel = styled.div`
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;

  width: 48px;
  height: 16px;
  background-color: ${(props) => (props.isChecked ? '#FAE585' : '#EFF1F3')};

  border-radius: 100px;
  transition: background-color 0.2s;
  cursor: pointer;
`;

const ToggleButton = ({ isChecked }) => {
  return (
    <>
      <SwitchLabel isChecked={isChecked}>
        <SwitchButton isChecked={isChecked} />
      </SwitchLabel>
    </>
  );
};

📓 05. 프로젝트 기획기간 인터렉티브 버튼 모음 제작

저는 기획 기간동안 개발자로서 제 할일을 찾기 시작했습니다. 그 결과 기획 기간 동안, 필요한 기능들을 구현해보고자 하였고, 그렇게 만들어진 것이 인터렉티브 버튼 모음이라는 미니프로젝트 입니다.

  • 인터랙티브 버튼 모음
    1) 배경 : 프로젝트 기획 도중 나온 컨셉 중 하나가 인터렉티브였습니다. 컨셉을 위해서는 사용자의 행동을 끌어내는 기능이 필요했고, 이를 활용할 기술 공부가 필요했습니다.
    2) 포인트 : 최대한 깔끔한 형태로 제작하고자 하였고, 라이브러리를 최대한 지양하며, 라이브러리를 사용해야한다면 단순하게 그 자체를 가져와 쓰는 것이 아닌, 제가 원하는 형태로 최대한 구현하고자 하였습니다.
    3) 페이지별 이미지
스위치드래그 앤 드롭
라이브러리 사용하지 않음
반응이 잘 표현되도록 스위치 제작
react-beautiful-dnd
활용 제작
드롭 리스트캐러셀
react-beautiful-dnd
활용 제작
라이브러리 사용하지 않음
반응이 잘 표현되도록 스위치 제작

💌 06. 마치며

하나의 프로젝트에 얼마나 많은 사람들의 고민과 생각, 진심이 녹아있는지 다시금 깨달을 수 있었던 프로젝트였습니다.
프로젝트를 개발을 하는 동안, 좋은 생각과 디자인이 모인 집합체를 구현하는 것이 얼마나 매력적인가 생각이 들었고, 개발자가 꼭 되고 싶다고 생각했습니다.

profile
고객에게 명료한 의미를 전달하고, 명료한 코드를 통해 생산성 향상에 기여하고자 노력합니다.

0개의 댓글