๐Ÿ“Š Profile ๊ธฐ๋Šฅ ๊ณ ๋„ํ™” โ€“ ํŒ”๋กœ์ž‰/ํŒ”๋กœ์›Œ UI ๊ตฌ์„ฑ๊ณผ ์ˆซ์ž ํฌ๋งท ๊ณ ๋ฏผ๊ธฐ

์กฐ์ค€ํ˜•ยท2025๋…„ 4์›” 9์ผ
0

CHOP!

๋ชฉ๋ก ๋ณด๊ธฐ
15/20
post-thumbnail

์ด์ „๊นŒ์ง€๋Š” ๋‹จ์ˆœํžˆ ๋‚˜์˜ ํ”„๋กœํ•„๊ณผ ๊ฑฐ๋ž˜ ํ†ต๊ณ„ ์ •๋„๋งŒ ๋ณด์—ฌ์ฃผ๋Š” ๊ตฌ์กฐ์˜€์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ๋” ๋งŽ์€ ์†Œ์…œ์  ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ํŒ”๋กœ์ž‰/ํŒ”๋กœ์›Œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค. ๋˜ํ•œ ์ˆซ์ž ํฌ๋งท, ์‘๋‹ต ์‹œ๊ฐ„ ํ‘œ์‹œ, ์ „ํˆฌ๋ ฅ ํ‘œํ˜„ ๋“ฑ์—์„œ ์œ ํ‹ธ ํ•จ์ˆ˜ ๋ถ„๋ฆฌ ๋ฐ ํฌ๋งท ์ •ํ™”๋„ ํ•จ๊ป˜ ์ง„ํ–‰ํ–ˆ๋‹ค.

โœ… ํŒ”๋กœ์ž‰ / ํŒ”๋กœ์›Œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€

๐Ÿ“Œ ์–ด๋А ์ •๋ณด๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณด์—ฌ์ค„๊นŒ?

ProfileData์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๊ฐ€ ์žˆ์—ˆ๋‹ค:

{
  following: ["userId1", "userId2", ...],
  followers: ["userId3", "userId4", ...],
}

๋‹จ์ˆœํžˆ ์œ ์ € ID ๋ฐฐ์—ด๋งŒ ์žˆ์–ด์„œ, ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ ์œ ์ € ID์— ๋Œ€ํ•ด ๋‹ค์‹œ API ํ˜ธ์ถœ์ด ํ•„์š”ํ–ˆ๋‹ค.

const followingProfiles = await Promise.all(
  following.map(userId => shootingStar.launch(GetProfileByUserIDGameIDWing(userId, gameID)))
)

โ†’ ๊ฐ๊ฐ์˜ userID์— ๋Œ€ํ•ด ๋‹ค์‹œ ProfileData๋ฅผ ๋ฐ›์•„์™€์•ผ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ์Œ.

๐ŸŽ› UI ๊ตฌ์„ฑ

๋ฒ„ํŠผ์€ ์ขŒ์šฐ ์–‘๋ฐฉํ–ฅ ํ† ๊ธ€์œผ๋กœ ๊ตฌ์„ฑ:

<FavoriteButton
  onLeftClick={handleLeftButtonClick}
  onRightClick={handleRightButtonClick}
  FollowingNumber={followingProfiles.length}
  FollowerNumber={followerProfiles.length}
/>
  • ๋‚ด๊ฐ€ ์ฆ๊ฒจ์ฐพ๋Š” โ†’ ํŒ”๋กœ์ž‰ ๋ชฉ๋ก

  • ๋‚˜๋ฅผ ์ฆ๊ฒจ์ฐพ๋Š” โ†’ ํŒ”๋กœ์›Œ ๋ชฉ๋ก

ํ•ด๋‹น ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ, ๊ฐ๊ฐ visibleSection์„ ์—…๋ฐ์ดํŠธํ•ด์„œ ์•„๋ž˜์— ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ณด์—ฌ์ง€๋„๋ก ๊ตฌ์„ฑ:


{visibleSection === 'following' && followingProfiles.map(...) }
{visibleSection === 'follower' && followerProfiles.map(...) }

FollowContainer, FollowerContainer๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ•ด ์Šคํƒ€์ผ ์œ ์ง€์™€ ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ๊ฐ€ ๊น”๋”ํ•ด์กŒ๋‹ค.

๐Ÿ“€ ์ˆซ์ž ํฌ๋งท๊ณผ ์œ ํ‹ธ ํ•จ์ˆ˜

๐Ÿง  ๋ฌธ์ œ ์ƒํ™ฉ

  • ์ „ํˆฌ๋ ฅ: 14,213,000 โ†’ 1,000๋งŒ+ ์‹์œผ๋กœ ์ถ•์•ฝ

  • ์‘๋‹ต ์‹œ๊ฐ„: 1,542,300 ๋งˆ์ดํฌ๋กœ์ดˆ โ†’ 1.5์ดˆ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜

  • ์žฌ๊ฑฐ๋ž˜์œจ: 0.864444444%์ฒ˜๋Ÿผ ๋„ˆ๋ฌด ๊ธด ์‹ค์ˆ˜ โ†’ ๋ถˆํŽธํ•˜๊ณ  ์ง€์ €๋ถ„ํ•œ ํ‘œํ˜„

์ฒ˜์Œ์—๋Š” toFixed() ๊ฐ™์€ ๋‚ด์žฅ ํ•จ์ˆ˜๋งŒ ์“ฐ๊ธฐ๋„ ํ–ˆ์ง€๋งŒ, ๊ฒฐ๊ตญ ์ค‘๋ณต๋˜๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง€๋Š” ๊ฑธ ๋ง‰๊ธฐ ์œ„ํ•ด utils๋กœ ๋ถ„๋ฆฌํ–ˆ๋‹ค.

๋˜ํ•œ ์ด ๊ณผ์ •์—์„œ toFixed(1)์ด ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์ ๋„ ๊ณ ๋ คํ•˜๊ฒŒ ๋๋Š”๋ฐ, ์˜ˆ๋ฅผ ๋“ค์–ด 0.864444444.toFixed(1)์€ ๋ฌธ์ž์—ด "0.9"๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ˆซ์ž ๊ณ„์‚ฐ์ด ํ•„์š”ํ•œ UI์—๋Š” ์ ์ ˆํ•˜์ง€ ์•Š์•˜๋‹ค. ๋Œ€์‹  Math.floor๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์ˆ˜ ์ฒ˜๋ฆฌ๋ฅผ ์ง์ ‘ ์ œ์–ดํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฐœ์„ ํ–ˆ๋‹ค.

๐Ÿ”‹ ์ „ํˆฌ๋ ฅ ํ‘œํ˜„: formatPower

์ด ํ•จ์ˆ˜์—์„œ ํ•ต์‹ฌ์€ ๋‹จ์ˆœํžˆ ๋‹จ์œ„๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๋ฟ ์•„๋‹ˆ๋ผ, Math.floor()๋ฅผ ํ™œ์šฉํ•ด์„œ ์†Œ์ˆ˜์  ์—†์ด ์ •์ˆ˜๋กœ '๋”ฑ ๋Š์–ด๋‚ด๋Š”' ์ฒ˜๋ฆฌ๋ฅผ ํ•จ๊ป˜ ์ ์šฉํ–ˆ๋‹ค๋Š” ์ ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 54213000์€ 5.4213์ฒœ๋งŒ์ด์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ 5์ฒœ๋งŒ์œผ๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Math.floor(power / 10000000) ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑํ–ˆ๋‹ค. โ†’ ์†Œ์ˆ˜์  ์ดํ•˜๋ฅผ ๋ฒ„๋ฆฌ๊ณ  ๋‹จ์œ„๋ฅผ ๋Š์–ด์ฃผ๋Š” ๋ฐฉ์‹.

export const formatPower = (power: number): string => {
    if (power >= 100000000) {
        const billions = Math.floor(power / 100000000);
        return `${billions}์–ต`;
    } else if (power >= 10000000) {
        const tenMillions = Math.floor(power / 10000000);
        return `${tenMillions}์ฒœ๋งŒ`;
    } else if (power >= 10000) {
        const tenThousand = Math.floor(power / 10000);
        return `${tenThousand}๋งŒ`;
    } else {
        return power.toLocaleString();
    }
};

๐Ÿ“Œ ์ž‘๋™ ๋ฐฉ์‹ ์˜ˆ์‹œ

์ž…๋ ฅ ์ „ํˆฌ๋ ฅ			์ถœ๋ ฅ ๋ฌธ์ž์—ด

1234				1,234

120000				12๋งŒ

987654321			9์–ต

20000000			2์ฒœ๋งŒ

54213000			5์ฒœ๋งŒ

์ด ๊ตฌ์กฐ๋Š” "์ฒœ๋งŒ" ๋‹จ์œ„ ํ‘œํ˜„๋„ ์ง€์›ํ•ด์„œ, ์–ต ๋‹จ์œ„๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์• ๋งคํ•œ ์ˆซ์ž๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋‹จ์œ„ ๋Š์–ด์„œ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Œ
โ†’ ์ˆซ์ž ๊ทœ๋ชจ๊ฐ€ ํด์ˆ˜๋ก ์‹œ๊ฐ์ ์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ ๊ฐ€๋Šฅํ•˜๊ณ , ๊ฐ€๋…์„ฑ๊ณผ ์ „๋‹ฌ๋ ฅ์ด ํ–ฅ์ƒ๋จ

๐Ÿ” ์žฌ๊ฑฐ๋ž˜์œจ ํ‘œํ˜„: FormatRetrade

์ž‘์—… ์ค‘ "๊ทธ๋ƒฅ ์„œ๋ฒ„์—์„œ ์ •์ˆ˜๋กœ ์ž˜๋ผ์„œ ์ฃผ๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€?"๋ผ๋Š” ์š”์ฒญ๋„ ํ–ˆ๋Š”๋ฐ, ์ด์— ๋Œ€ํ•ด ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์„ค๋ช…ํ•˜๊ธธ:
"๊ฐ™์€ ํฌ๋งท์„ ์—ฌ๋Ÿฌ API์—์„œ ๊ณต์œ ํ•ด์•ผ ํ•˜๊ณ , ์ด๊ฑธ ์„œ๋ฒ„์—์„œ ๋งค๋ฒˆ ๊ฐ€๊ณตํ•˜๋ฉด ์˜คํžˆ๋ ค ์ž์› ๋‚ญ๋น„๊ฐ€ ํฌ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•œ ์ค„๋กœ ์ž๋ฅด๊ณ  ์“ฐ๋Š” ๊ฒŒ ๋ถ€๋‹ด๋„ ์ ๊ณ  ํ™•์žฅ์„ฑ๋„ ์ข‹๋‹ค"๊ณ  ํ–ˆ๋‹ค.

์‹ค์ œ๋กœ ํ”„๋ก ํŠธ์—์„œ๋Š” Math.floor๋กœ ์ž˜๋ผ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๋‹ˆ๊นŒ, ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ๋„ ๋” ํ•ฉ๋ฆฌ์ ์ด์—ˆ๋‹ค.

  • ์žฌ๊ฑฐ๋ž˜์œจ์€ ์ˆซ์ž ํ˜•ํƒœ๋กœ ๋“ค์–ด์˜ค๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค:
// 0.864444444 โ†’ ๋„ˆ๋ฌด ๋ณด๊ธฐ ๋ถˆํŽธํ•จ!

๊ทธ๋ž˜์„œ ์œ ์ €๊ฐ€ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํผ์„ผํŠธ ๋‹จ์œ„๋กœ ์ •๋ฆฌํ•ด์„œ ํ‘œํ˜„ํ–ˆ๋‹ค.

export const FormatRetrade = (retrade: number): number => {
  const FormattedRetrade = Math.floor(retrade * 100);
  return FormattedRetrade;
};
0.743 โ†’ 74%

0.812 โ†’ 81%

0.864444444 โ†’ 86%

toFixed()๋ฅผ ์“ฐ๋ฉด "0.9"์ฒ˜๋Ÿผ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜๋˜์–ด ์žฌ์‚ฌ์šฉ์ด ๋ถˆํŽธํ•˜์ง€๋งŒ,
Math.floor๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ˆซ์ž ๊ทธ๋Œ€๋กœ ๋”ฑ ๋–จ์–ด์ง€๋Š” ์ •์ˆ˜๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•ด์„œ ํผ์„ผํŠธ ํ‘œํ˜„์— ๋” ์ ํ•ฉํ–ˆ๋‹ค.

โœจ ์ตœ์ข… ๊ฒฐ๊ณผ: Profile.tsx ํ™œ์šฉ ์˜ˆ

<StatusBadge
  level={mainCharacter?.level}
  power={formatPower(mainCharacter?.power || 0)}
  union={mainCharacter?.union}
/>

<TradeStatus
  popularity={profileData.stat.popularity}
  retrade_rate={FormatRetrade(profileData.stat.retrade_rate)}
  response_time={convertMicrosecondsToTime(profileData.stat.mean_response_time)}
/>
  • ์œ ํ‹ธ ํ•จ์ˆ˜๋กœ ๋ชจ๋“  ์ˆซ์ž ํ‘œํ˜„์ด ํ‘œ์ค€ํ™”๋จ

  • ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ง€๋Š” ์ •๋ณด๊ฐ€ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์ง๊ด€์ ์ž„

๐Ÿง  ํšŒ๊ณ 

โ€œ์ˆซ์ž ํ•˜๋‚˜์—๋„ UX๊ฐ€ ์žˆ๋‹ค.โ€

์ˆซ์ž ํ‘œํ˜„์€ ๋‹จ์ˆœํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ, ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ ์œ ์ €๋ฅผ ์–ด๋–ค ๋А๋‚Œ์œผ๋กœ ์ธ์‹ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์‹œ๊ฐ ์š”์†Œ๋‹ค.

์ „ํˆฌ๋ ฅ์€ ์‹œ์›ํ•˜๊ฒŒ ๋Š์–ด์ง„ ๋‹จ์œ„๋กœ,
ํผ์„ผํŠธ๋Š” ์งง๊ณ  ๋ช…ํ™•ํ•œ ์ •์ˆ˜๋กœ ํ‘œํ˜„ํ•˜๋‹ˆ ์ „์ฒด ํ”„๋กœํ•„ ํ™”๋ฉด์ด ์‹ ๋ขฐ๊ฐ ์žˆ๊ณ  ์ •๋ˆ๋œ ๋А๋‚Œ์„ ์ฃผ๊ฒŒ ๋˜์—ˆ๋‹ค.

์•ž์œผ๋กœ๋„ ๋ชจ๋“  ์ˆซ์ž ํ‘œํ˜„์€ ์œ ํ‹ธ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ์‚ฌ์šฉ์ž ๊ด€์ ์˜ ์ •๋ณด ์ „๋‹ฌ์„ ์šฐ์„ ํ•˜๊ฒ ๋‹ค.

profile
์ฝ”๋ฆฐ์ด

0๊ฐœ์˜ ๋Œ“๊ธ€