Skip to content

Commit

Permalink
init MBTICompatibility test
Browse files Browse the repository at this point in the history
  • Loading branch information
kapable committed Dec 10, 2024
1 parent 0e0b768 commit df4f9fd
Show file tree
Hide file tree
Showing 12 changed files with 426 additions and 1 deletion.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6979,7 +6979,8 @@
"/idealTypeBingoMale",
"/kapable.github.io/idealTypeBingoMale",
"/idealTypeBingoFemale",
"/kapable.github.io/idealTypeBingoFemale"
"/kapable.github.io/idealTypeBingoFemale",
"/compatibility"
]
},
"eslintConfig": {
Expand Down
15 changes: 15 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ import ShortAnswerQuizResult from './components/TestTypes/ShortAnswerQuiz/ShortA
import { shortAnswerQuizesTitle } from './api/SHORTANSWERQUIZ';
import AuthCallback from './pages/Auth/AuthCallback';
import Admin from './pages/admin/Admin';
import MBTICompatibility, {
mbti_array,
} from './components/TestTypes/MBTICompatibility/MBTICompatibility';
import CompatibilityResult from './components/TestTypes/MBTICompatibility/CompatibilityResult';

let mbti_results_set = [];

Expand Down Expand Up @@ -234,6 +238,17 @@ function App() {
element={<ColorPickerResult lang={item.lang} />}
/>
))}
{/* MBTI Compatibility */}
<Route path='/compatibility/' element={<MBTICompatibility />} />
{mbti_array.map((first) =>
mbti_array.map((second) => (
<Route
key={`/compatibility/${first.value}-${second.value}/`}
path={`/compatibility/${first.value}-${second.value}/`} //
element={<CompatibilityResult />}
/>
))
)}
{/* Dual Quries Tests */}
{/* go to "HaGender" page */}
<Route
Expand Down
35 changes: 35 additions & 0 deletions src/components/TestTypes/MBTICompatibility/CompatibilityDesc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';

const CompatibilityDesc = ({ result }) => {
return (
<div
style={{
border: '1px solid black',
borderRadius: '1rem',
padding: '0.7rem',
margin: '2rem auto',
}}
>
<p style={{ lineHeight: '1.5rem', textAlign: 'left' }}>
{result?.desc
?.replaceAll('"', '')
?.replaceAll('”', '')
?.replaceAll('“', '')
?.split('.')
.map((sentence, index) => (
<React.Fragment key={index}>
{sentence.trim()}
{index < result.desc.split('.').length - 1 && (
<>
<br />
<br />
</>
)}
</React.Fragment>
))}
</p>
</div>
);
};

export default CompatibilityDesc;
69 changes: 69 additions & 0 deletions src/components/TestTypes/MBTICompatibility/CompatibilityResult.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router';
import { supabase } from '../../../tools/supabaseClient';
import { MBTI_COMP } from '../../../tools/auth';
import MBTITypes from './MBTITypes';
import CompatibilityScores from './CompatibilityScores';
import CompatibilityDesc from './CompatibilityDesc';
import GoToHomeBtn from '../../Sub/GoToHomeBtn';
import { LoadingOutlined } from '@ant-design/icons';
import { Button } from 'antd';

const CompatibilityResult = () => {
const navigate = useNavigate();
const location = useLocation();
const [myType] = useState(location.pathname.split('/')?.[2].split('-')[0]);
const [yourType] = useState(location.pathname.split('/')?.[2].split('-')[1]);
const [result, setResult] = useState(null);

useEffect(() => {
const fetchCompatibility = async () => {
try {
const { data } = await supabase
.from(MBTI_COMP)
.select('*')
.eq('MBTI1', myType)
.eq('MBTI2', yourType)
.single();

if (!data) {
const { data } = await supabase
.from(MBTI_COMP)
.select('*')
.eq('MBTI2', myType)
.eq('MBTI1', yourType)
.single();
return setResult(data);
}
return setResult(data);
} catch (error) {
return alert('에러가 발생했어요!');
}
};
fetchCompatibility();
}, [myType, yourType]);

return (
<div style={{ width: '100%', maxWidth: '25rem', margin: '0 auto' }}>
<MBTITypes myType={myType} yourType={yourType} />
{result ? (
<>
<CompatibilityScores result={result} />
<CompatibilityDesc result={result} />
<Button
style={{ width: '100%', height: '3rem' }}
type='primary'
onClick={() => navigate('/compatibility/')}
>
다시하기
</Button>
</>
) : (
<LoadingOutlined style={{ fontSize: '7rem', margin: '2rem auto' }} />
)}
<GoToHomeBtn page={`compatibility result`} />
</div>
);
};

export default CompatibilityResult;
81 changes: 81 additions & 0 deletions src/components/TestTypes/MBTICompatibility/CompatibilityScores.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Col, Divider, Row } from 'antd';
import React from 'react';

const CompatibilityScores = ({ result }) => {
const keyDict = {
expression: '로맨틱 표현력',
intimacy: '의사소통의 친밀도',
resolution: '갈등 해결 능력',
contribution: '장기적 헌신 가능성',
passion: '열정과 설렘 유지',
understanding: '서로에 대한 이해',
interest: '공유된 관심사',
date: '데이트 만족도',
reliability: '신뢰 수준',
marriage: '결혼 가능성 점수',
discord: '불화 가능성 점수',
stability: '감정적 안정성',
};

return (
<div>
<h1>{result?.keywords}</h1>
<h2>연애 궁합 총점: {result?.total_score}</h2>
<Row gutter={16}>
{Object.keys(result)?.map((key) => {
if (
key !== 'no' &&
key !== 'keywords' &&
key !== 'desc' &&
key !== 'MBTI1' &&
key !== 'MBTI2' &&
key !== 'total_score'
) {
return (
<Col key={key} span={8}>
<div
style={{
// backgroundColor:

border: '1px solid black',
borderRadius: '1rem',
padding: '0.1rem',
height: '7rem',
margin: '0.5rem auto',
}}
>
<p
style={{
fontSize: '0.7rem',
fontWeight: 'bold',
}}
>
{keyDict?.[key]}
</p>
<Divider />
<p
style={{
fontWeight: 'bold',
fontSize: '1.3rem',
// color:
// result?.[key] >= 70
// ? 'green'
// : result?.[key] >= 45
// ? 'gold'
// : 'pink',
}}
>
{result?.[key]}
</p>
</div>
</Col>
);
}
return null;
})}
</Row>
</div>
);
};

export default CompatibilityScores;
70 changes: 70 additions & 0 deletions src/components/TestTypes/MBTICompatibility/MBTICompatibility.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { useState } from 'react';
import ProgramTItle from './ProgramTItle';
import MBTISelector from './MBTISelector';
import ProgramButtonGroup from './ProgramButtonGroup';
import { Modal } from 'antd';
import Lottie from 'react-lottie';
import * as loading from '../../../loading-animation.json';
import GoToHomeBtn from '../../Sub/GoToHomeBtn';

export const mbti_array = [
{ value: 'ESTJ', label: 'ESTJ' },
{ value: 'ESFJ', label: 'ESFJ' },
{ value: 'ISTJ', label: 'ISTJ' },
{ value: 'ISFJ', label: 'ISFJ' },
{ value: 'ESTP', label: 'ESTP' },
{ value: 'ESFP', label: 'ESFP' },
{ value: 'ISTP', label: 'ISTP' },
{ value: 'ISFP', label: 'ISFP' },
{ value: 'ENTJ', label: 'ENTJ' },
{ value: 'ENFJ', label: 'ENFJ' },
{ value: 'INTJ', label: 'INTJ' },
{ value: 'INFJ', label: 'INFJ' },
{ value: 'ENTP', label: 'ENTP' },
{ value: 'ENFP', label: 'ENFP' },
{ value: 'INTP', label: 'INTP' },
{ value: 'INFP', label: 'INFP' },
];

const defaultOptions = {
loop: true,
autoplay: true,
animationData: loading.default,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
};

const MBTICompatibility = () => {
const [myTypes, setMyType] = useState(mbti_array[0].value);
const [yourTypes, setYourType] = useState(mbti_array[0].value);
const [mode, setMode] = useState('intro');

return (
<div style={{ width: '100%', maxWidth: '25rem', margin: '0 auto' }}>
<ProgramTItle />
<MBTISelector
mbti_array={mbti_array}
setMyType={setMyType}
setYourType={setYourType}
/>
<ProgramButtonGroup
myTypes={myTypes}
yourTypes={yourTypes}
setMode={setMode}
mode={mode}
/>
{mode === 'loading' && (
<Modal
title={<Lottie options={defaultOptions} height={120} width={120} />}
open={mode === 'loading'}
footer={null}
closable={false}
/>
)}
<GoToHomeBtn page={`compatibility intro`} />
</div>
);
};

export default MBTICompatibility;
38 changes: 38 additions & 0 deletions src/components/TestTypes/MBTICompatibility/MBTISelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { Col, Row, Select } from 'antd';

const MBTISelector = ({ mbti_array, setMyType, setYourType }) => {
return (
<div style={{ margin: '3rem auto' }}>
<Row align={'middle'} justify={'center'}>
<Col span={11}>
<div style={{ margin: '0.5rem auto' }}></div>
<Select
style={{
width: '100%',
}}
options={mbti_array}
defaultValue={mbti_array[0]}
onChange={(value) => setMyType(value)}
/>
</Col>
<Col span={2}>
<div style={{ margin: '0.5rem auto' }}>&nbsp;</div>+
</Col>
<Col span={11}>
<div style={{ margin: '0.5rem auto' }}>상대방</div>
<Select
style={{
width: '100%',
}}
options={mbti_array}
defaultValue={mbti_array[0]}
onChange={(value) => setYourType(value)}
/>
</Col>
</Row>
</div>
);
};

export default MBTISelector;
35 changes: 35 additions & 0 deletions src/components/TestTypes/MBTICompatibility/MBTITypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Col, Row } from 'antd';
import React from 'react';

const MBTITypes = ({ myType, yourType }) => {
return (
<div>
<h1>MBTI 연애 궁합 테스트 결과</h1>
<h3 style={{ color: '#E71C83' }}>by 케이테스트</h3>
<Row
style={{
border: '1px solid black',
borderRadius: '1rem',
margin: '1.5rem auto',
padding: '1rem',
}}
>
<Col span={11}>
<div>나의 MBTI</div>
<div style={{ fontWeight: 'bold', fontSize: '1.5rem' }}>{myType}</div>
</Col>
<Col span={2}>
<div>&nbsp;</div>+
</Col>
<Col span={11}>
<div>상대 MBTI</div>
<div style={{ fontWeight: 'bold', fontSize: '1.5rem' }}>
{yourType}
</div>
</Col>
</Row>
</div>
);
};

export default MBTITypes;
Loading

0 comments on commit df4f9fd

Please sign in to comment.