From 5f25fdb6e7ebee2227b71c0f85e09b0a78b5b725 Mon Sep 17 00:00:00 2001 From: hyochan Date: Fri, 9 Aug 2024 01:39:57 +0900 Subject: [PATCH] feat: render combat details --- app/(app)/(tabs)/profile.tsx | 51 +++----- src/apis/githubStatsQueries.ts | 3 +- src/components/fragments/DoobooStats.tsx | 60 +++++++++ src/components/svgs/SvgStatsDooboo.tsx | 14 ++- src/components/svgs/SvgStatsEarth.tsx | 15 ++- src/components/svgs/SvgStatsFire.tsx | 15 ++- src/components/svgs/SvgStatsGold.tsx | 13 +- src/components/svgs/SvgStatsPerson.tsx | 15 ++- src/components/svgs/SvgStatsTree.tsx | 11 +- src/components/svgs/SvgStatsWater.tsx | 16 ++- src/components/uis/Scouter/CombatDetails.tsx | 123 +++++++++++-------- src/components/uis/Scouter/StatsChart.tsx | 8 +- src/types/github-stats.ts | 2 +- src/utils/constants.ts | 2 +- 14 files changed, 223 insertions(+), 125 deletions(-) create mode 100644 src/components/fragments/DoobooStats.tsx diff --git a/app/(app)/(tabs)/profile.tsx b/app/(app)/(tabs)/profile.tsx index ef88298..8efd542 100644 --- a/app/(app)/(tabs)/profile.tsx +++ b/app/(app)/(tabs)/profile.tsx @@ -9,10 +9,7 @@ import {css} from '@emotion/native'; import {Pressable} from 'react-native'; import {IC_ICON} from '../../../src/icons'; import {openURL} from '../../../src/utils/common'; -import {useEffect, useState} from 'react'; -import {updateDoobooGithub} from '../../../src/apis/githubStatsQueries'; -import Scouter from '../../../src/components/uis/Scouter'; -import {DoobooGithubStats} from '../../../src/types/github-stats'; +import DoobooStats from '../../../src/components/fragments/DoobooStats'; const Container = styled.SafeAreaView` flex: 1; @@ -46,13 +43,20 @@ const UserName = styled(Typography.Heading5)` margin-bottom: 8px; `; -const UserBio = styled.Text` +const UserAffiliation = styled.Text` font-size: 16px; color: ${({theme}) => theme.role.secondary}; text-align: center; margin-bottom: 16px; `; +const UserBio = styled.Text` + font-size: 16px; + color: ${({theme}) => theme.text.label}; + text-align: center; + margin-bottom: 16px; +`; + const InfoCard = styled.View` background-color: ${({theme}) => theme.bg.paper}; border-radius: 15px; @@ -76,9 +80,7 @@ const InfoLabel = styled(Typography.Body2)` font-family: Pretendard-Bold; `; -const InfoValue = styled(Typography.Body2)` - flex: 1; -`; +const InfoValue = styled(Typography.Body2)``; const TagContainer = styled.View` flex-direction: row; @@ -100,25 +102,8 @@ const TagText = styled.Text` export default function Profile(): JSX.Element { const {user, tags} = useRecoilValue(authRecoilState); - const [doobooStats, setDoobooStats] = useState( - null, - ); const {theme} = useDooboo(); - useEffect(() => { - const fetchGithubStats = async () => { - const result = await updateDoobooGithub(user!.github_id!); - - if (!!result?.stats) { - setDoobooStats(result.stats); - } - }; - - if (!!user?.github_id) { - fetchGithubStats(); - } - }, [user, user?.github_id]); - return ( {user?.display_name || ''} + {user?.affiliation ? ( + {user?.affiliation} + ) : null} {user?.introduction ? {user?.introduction} : null} @@ -155,19 +143,8 @@ export default function Profile(): JSX.Element { {user?.github_id || ''} - {doobooStats ? ( - - ) : null} + - {user?.affiliation ? ( - - {t('onboarding.affiliation')} - {user.affiliation} - - ) : null} {user?.desired_connection || user?.future_expectations ? ( diff --git a/src/apis/githubStatsQueries.ts b/src/apis/githubStatsQueries.ts index b3c3701..95fdb1b 100644 --- a/src/apis/githubStatsQueries.ts +++ b/src/apis/githubStatsQueries.ts @@ -14,8 +14,7 @@ export const updateDoobooGithub = async ( }); if (!response.ok) { - if (__DEV__) console.error('HTTP error! status:', response.status); - return; + throw new Error('HTTP error! status:' + response.status); } return await response.json(); diff --git a/src/components/fragments/DoobooStats.tsx b/src/components/fragments/DoobooStats.tsx new file mode 100644 index 0000000..e782f13 --- /dev/null +++ b/src/components/fragments/DoobooStats.tsx @@ -0,0 +1,60 @@ +import styled, {css} from '@emotion/native'; +import {useEffect, useState} from 'react'; +import {DoobooGithubStats} from '../../types/github-stats'; +import {updateDoobooGithub} from '../../apis/githubStatsQueries'; +import Scouter from '../uis/Scouter'; +import {User} from '../../types'; +import CustomLoadingIndicator from '../uis/CustomLoadingIndicator'; + +const Container = styled.View``; + +type Props = { + user: User | null; +}; + +export default function DoobooStats({user}: Props): JSX.Element | null { + const [doobooStats, setDoobooStats] = useState( + null, + ); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchGithubStats = async () => { + try { + if (!user?.github_id) { + return; + } + const result = await updateDoobooGithub(user!.github_id!); + + if (!!result?.stats) { + setDoobooStats(result.stats); + } + } catch (e: any) { + setError(e.message); + } + }; + + if (!!user?.github_id) { + fetchGithubStats(); + } + }, [user, user?.github_id]); + + if (error) { + return null; + } + + return ( + + {doobooStats ? ( + + ) : ( + + )} + + ); +} diff --git a/src/components/svgs/SvgStatsDooboo.tsx b/src/components/svgs/SvgStatsDooboo.tsx index d787b11..bd67b40 100644 --- a/src/components/svgs/SvgStatsDooboo.tsx +++ b/src/components/svgs/SvgStatsDooboo.tsx @@ -1,16 +1,24 @@ +import { useDooboo } from 'dooboo-ui'; import {Svg, G, Path, Defs, ClipPath, Rect} from 'react-native-svg'; -export default function SvgStatsDooboo() { +type Props = { + color?: string; +}; + +export default function SvgStatsDooboo({color}: Props) { + const {theme} = useDooboo(); + const fill = color || theme.text.basic; + return ( diff --git a/src/components/svgs/SvgStatsEarth.tsx b/src/components/svgs/SvgStatsEarth.tsx index b7722e4..fec734d 100644 --- a/src/components/svgs/SvgStatsEarth.tsx +++ b/src/components/svgs/SvgStatsEarth.tsx @@ -1,23 +1,28 @@ -import { useDooboo } from 'dooboo-ui'; +import {useDooboo} from 'dooboo-ui'; import {G, Path, Svg} from 'react-native-svg'; -export default function SvgStatsEarth() { +type Props = { + color?: string; +}; + +export default function SvgStatsEarth({color}: Props) { const {theme} = useDooboo(); + const fill = color || theme.text.basic; return ( diff --git a/src/components/svgs/SvgStatsFire.tsx b/src/components/svgs/SvgStatsFire.tsx index 05da8c9..e34527b 100644 --- a/src/components/svgs/SvgStatsFire.tsx +++ b/src/components/svgs/SvgStatsFire.tsx @@ -1,23 +1,28 @@ -import { useDooboo } from 'dooboo-ui'; +import {useDooboo} from 'dooboo-ui'; import {G, Path, Svg} from 'react-native-svg'; -export default function SvgStatsFire() { +type Props = { + color?: string; +}; + +export default function SvgStatsFire({color}: Props) { const {theme} = useDooboo(); + const fill = color || theme.text.basic; return ( diff --git a/src/components/svgs/SvgStatsGold.tsx b/src/components/svgs/SvgStatsGold.tsx index adcd45d..1eeed17 100644 --- a/src/components/svgs/SvgStatsGold.tsx +++ b/src/components/svgs/SvgStatsGold.tsx @@ -1,23 +1,28 @@ import {useDooboo} from 'dooboo-ui'; import {G, Path, Svg} from 'react-native-svg'; -export default function SvgStatsGold() { +type Props = { + color?: string; +}; + +export default function SvgStatsGold({color}: Props) { const {theme} = useDooboo(); + const fill = color || theme.text.basic; return ( diff --git a/src/components/svgs/SvgStatsPerson.tsx b/src/components/svgs/SvgStatsPerson.tsx index f3356fa..a7de333 100644 --- a/src/components/svgs/SvgStatsPerson.tsx +++ b/src/components/svgs/SvgStatsPerson.tsx @@ -1,27 +1,32 @@ import {useDooboo} from 'dooboo-ui'; import {G, Path, Svg} from 'react-native-svg'; -export default function SvgStatsPerson() { +type Props = { + color?: string; +}; + +export default function SvgStatsPerson({color}: Props) { const {theme} = useDooboo(); + const fill = color || theme.text.basic; return ( diff --git a/src/components/svgs/SvgStatsTree.tsx b/src/components/svgs/SvgStatsTree.tsx index d2b73b2..9c9819e 100644 --- a/src/components/svgs/SvgStatsTree.tsx +++ b/src/components/svgs/SvgStatsTree.tsx @@ -1,16 +1,21 @@ import {useDooboo} from 'dooboo-ui'; import {G, Path, Svg} from 'react-native-svg'; -export default function SvgStatsTree() { +type Props = { + color?: string; +}; + +export default function SvgStatsTree({color}: Props) { const {theme} = useDooboo(); + const fill = color || theme.text.basic; return ( - + diff --git a/src/components/svgs/SvgStatsWater.tsx b/src/components/svgs/SvgStatsWater.tsx index 4a4df46..322b674 100644 --- a/src/components/svgs/SvgStatsWater.tsx +++ b/src/components/svgs/SvgStatsWater.tsx @@ -1,20 +1,28 @@ +import {useDooboo} from 'dooboo-ui'; import {G, Path, Svg} from 'react-native-svg'; -export default function SvgStatsWater() { +type Props = { + color?: string; +}; + +export default function SvgStatsWater({color}: Props) { + const {theme} = useDooboo(); + const fill = color || theme.text.basic; + return ( diff --git a/src/components/uis/Scouter/CombatDetails.tsx b/src/components/uis/Scouter/CombatDetails.tsx index 133d3f3..a9db49e 100644 --- a/src/components/uis/Scouter/CombatDetails.tsx +++ b/src/components/uis/Scouter/CombatDetails.tsx @@ -92,60 +92,98 @@ const StatIcons = ({ onPress={() => onPressStat(null)} style={[style, {padding: 2}]} > - + onPressStat('tree')} style={[style, {padding: 2}]} > - + onPressStat('fire')} style={[style, {padding: 2}]} > - + onPressStat('earth')} style={[style, {padding: 2}]} > - + onPressStat('gold')} style={[style, {padding: 2}]} > - + onPressStat('water')} style={[style, {padding: 2}]} > - + onPressStat('people')} style={[style, {padding: 2}]} > - + ); }; -function ContentStatsDetails({ - statsElement, - details, -}: { - statsElement: StatsElement; - details: StatsDetail[]; -}): ReactElement { +const ContentDetailDescription = ({ + json, + stats, + selectedStats, +}: ContentDetailDescProps): ReactElement | null => { const {theme} = useDooboo(); + if (!stats) { + return null; + } + + const {name, description, statElements, score} = stats; + const renderCommonDetail = ({ + statsElement, statsDetails, }: { + statsElement: StatsElement; statsDetails?: ReactElement; }): ReactElement => { return ( @@ -154,7 +192,6 @@ function ContentStatsDetails({ style={{ marginBottom: 8, alignSelf: 'stretch', - flexDirection: 'row', justifyContent: 'space-between', }} @@ -164,8 +201,7 @@ function ContentStatsDetails({ key={statsElement.name} style={{minHeight: 24, fontWeight: 'bold'}} > - {statsElement.key} - {/* {getString(statsElement.key as any)} */} + {statsElement.name} @@ -173,7 +209,7 @@ function ContentStatsDetails({ style={{ minHeight: 24, marginBottom: 12, - color: theme.role.accent, + color: theme.role.info, }} > {statsElement.totalCount?.toLocaleString() || ''} @@ -185,12 +221,16 @@ function ContentStatsDetails({ ); }; - return (() => { + const renderDetails = ( + details: StatsDetail[], + statsElement: StatsElement, + ) => { switch (details.length) { case 0: - return renderCommonDetail({}); + return renderCommonDetail({statsElement}); case 1: return renderCommonDetail({ + statsElement, statsDetails: ( Linking.openURL(detail.url)} > {detail.name} @@ -221,10 +262,10 @@ function ContentStatsDetails({ case 'commit': return ( Linking.openURL( `https://github.com/${detail.name}/commit/${detail.sha}`, @@ -258,10 +299,10 @@ function ContentStatsDetails({ case 'language': return ( Linking.openURL(detail.url)} > {detail.name} @@ -315,10 +359,10 @@ function ContentStatsDetails({ case 'commit': return ( Linking.openURL( `https://github.com/${detail.name}/commit/${detail.sha}`, @@ -350,10 +394,10 @@ function ContentStatsDetails({ case 'language': return ( { - const {theme} = useDooboo(); - - if (!stats) { - return null; - } - - const {name, description, statsElements, score} = stats; + }; if (!selectedStats) { return ( @@ -429,7 +459,7 @@ const ContentDetailDescription = ({ ) : null} - {statsElements?.map((el: StatsElement) => { + {statElements?.map((el: StatsElement) => { if (!el.name) { return null; } @@ -438,10 +468,7 @@ const ContentDetailDescription = ({ ? JSON.parse(el.details) : []; - return ContentStatsDetails({ - details, - statsElement: el, - }); + return {renderDetails(details, el)}; })} diff --git a/src/components/uis/Scouter/StatsChart.tsx b/src/components/uis/Scouter/StatsChart.tsx index 02ee8de..c6f6aba 100644 --- a/src/components/uis/Scouter/StatsChart.tsx +++ b/src/components/uis/Scouter/StatsChart.tsx @@ -116,11 +116,9 @@ const convertPosition = ( const StatUnits = ({ centerPosition, - selectedStat, onPressStat, }: { centerPosition: Axis; - selectedStat?: StatType | null; onPressStat: (type: StatType) => void; }): ReactElement => { return ( @@ -232,11 +230,7 @@ const StatsChart = ({ return ( - +