Skip to content

Commit

Permalink
feat: 🚧 WIP: question page bare bones
Browse files Browse the repository at this point in the history
- missing slider
- missing storage of choices
- missing styles
  • Loading branch information
luximus-hunter committed Nov 26, 2024
1 parent 11d0af3 commit d8083d2
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 1 deletion.
21 changes: 21 additions & 0 deletions src/lib/repositories/scans/fetchScanQuestionRange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { fetchJsonData } from '../../fetcher/DataFetcher';
import { getEnvValue } from '../../utility/env/env';
import { EnvOptions } from '../../utility/env/env.values';
import { stringToBase64 } from '../../utility/stringutils';

export default function fetchScanQuestionRange(ids: string[]) {
const username = getEnvValue(EnvOptions.WordPressUsername);
const password = getEnvValue(EnvOptions.WordPressPassword);

return fetchJsonData({
input:
getEnvValue(EnvOptions.WordPressDataURL) +
'wp-json/wins/v1/app/questions/' +
ids.join(','),
init: {
headers: {
Authorization: `Basic ${stringToBase64(`${username}:${password}`)}`,
},
},
});
}
15 changes: 15 additions & 0 deletions src/lib/repositories/scans/useScanQuestionRange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ScanQuestion } from '../../../types/Scan';
import { useDataFetcher, fetchJsonData } from '../../fetcher/DataFetcher';
import { getEnvValue } from '../../utility/env/env';
import { EnvOptions } from '../../utility/env/env.values';

export default function useScanQuestionRange(ids: string[]) {
return useDataFetcher<ScanQuestion[]>(fetchJsonData, {
url:
getEnvValue(EnvOptions.WordPressDataURL) +
'wp-json/wins/v1/app/questions/' +
ids.join(','),
username: getEnvValue(EnvOptions.WordPressUsername),
password: getEnvValue(EnvOptions.WordPressPassword),
});
}
15 changes: 15 additions & 0 deletions src/lib/repositories/scans/useSingleScan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Scan } from '../../../types/Scan';
import { useDataFetcher, fetchJsonData } from '../../fetcher/DataFetcher';
import { getEnvValue } from '../../utility/env/env';
import { EnvOptions } from '../../utility/env/env.values';

export default function useSingleScan(id: string | undefined) {
return useDataFetcher<Scan>(fetchJsonData, {
url:
getEnvValue(EnvOptions.WordPressDataURL) +
'wp-json/wins/v1/app/scans/' +
id,
username: getEnvValue(EnvOptions.WordPressUsername),
password: getEnvValue(EnvOptions.WordPressPassword),
});
}
3 changes: 3 additions & 0 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { PodcastsEpisodePage } from '../screens/Podcasts/PodcastsEpisodePage';
import { PromptLibrary } from '../screens/PromptLibrary/PromptLibrary';
import { PromptView } from '../screens/PromptLibrary/PromptView';
import { Quizzes } from '../screens/Quizzes';
import { QuestionPage } from '../screens/Scans/QuestionPage';
import { SettingsScreen } from '../screens/Settings';
import { StudyScreen } from '../screens/Study';
import { CaseStudyInfo } from '../screens/Usecase/CaseStudyInfo';
Expand All @@ -23,6 +24,7 @@ import { BackgroundInfo } from '../screens/UserBackground/BackgroundInfo';
import { WTRScreen } from '../screens/WTR';
import { MockTutorial } from '../screens/WTR/MockTutorial';
import { WTRContentScreen } from '../screens/WTR/WTRContent';

const Stack = createNativeStackNavigator();

const screens = [
Expand All @@ -46,6 +48,7 @@ const screens = [
{ name: Routes.Quizzes, component: Quizzes },
{ name: Routes.MockTutorial, component: MockTutorial },
{ name: Routes.PodcastsEpisodePage, component: PodcastsEpisodePage },
{ name: Routes.QuestionPage, component: QuestionPage },
];

export const Router = () => {
Expand Down
3 changes: 2 additions & 1 deletion src/routes/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export const navigationBarLinks: NavigationBarLink[] = [
{ icon: 'articles', route: Routes.Articles },
{ icon: 'quizzes', route: Routes.Quizzes },
{ icon: 'prompts', route: Routes.PromptLibrary },
{ icon: 'WTR', route: Routes.WindesheimTechRadar },
{ icon: 'questions', route: Routes.QuestionPage },
// { icon: 'WTR', route: Routes.WindesheimTechRadar },

Check warning on line 14 in src/routes/navigation.ts

View workflow job for this annotation

GitHub Actions / check

Commented-out code is forbidden
];
6 changes: 6 additions & 0 deletions src/routes/routeLinking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ export const RouteLinking = {
[Routes.Quizzes]: 'quizzes',
[Routes.Articles]: 'articles',
[Routes.PodcastsEpisodePage]: 'podcasts/episode',
[Routes.QuestionPage]: {
path: 'scans/:scanId/questions',
parse: {
scanId: (scanId: string) => scanId,
},
},
},
},
};
1 change: 1 addition & 0 deletions src/routes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export enum Routes {
Prompts = 'Prompts',
MockTutorial = 'MockTutorial',
PodcastsEpisodePage = 'PodcastsEpisodePage',
QuestionPage = 'QuestionPage',
}

export const DefaultRoute = Routes.Home;
174 changes: 174 additions & 0 deletions src/screens/Scans/QuestionPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import React from 'react';
import { View, Text } from 'react-native';
import { Button, ProgressBar } from 'react-native-paper';

import fetchScanQuestionRange from '../../lib/repositories/scans/fetchScanQuestionRange';
import useScanQuestionRange from '../../lib/repositories/scans/useScanQuestionRange';
import useSingleScan from '../../lib/repositories/scans/useSingleScan';
import { ScanQuestion } from '../../types/Scan';

export function QuestionPage() {
const [currentQuestionIndex, setCurrentQuestionIndex] =
React.useState<number>(0);
const [currentQuestion, setCurrentQuestion] = React.useState<
ScanQuestion | undefined
>(undefined);
const [questions, setQuestions] = React.useState<ScanQuestion[]>([]);

const [questionCache, setQuestionCache] = React.useState<ScanQuestion[]>(
[],
);

const scanId = '1';

const {
data: scanData,
// isLoading: scanIsLoading,
// error: scanError,
} = useSingleScan(scanId);

const parsedQuestions: ScanQuestion[] = [];

if (scanData && parsedQuestions.length === 0) {
scanData.categories
.sort((a, b) => parseInt(a.idx, 10) - parseInt(b.idx, 10))

Check failure on line 34 in src/screens/Scans/QuestionPage.tsx

View workflow job for this annotation

GitHub Actions / check

Assignment of mutated arrays is forbidden
.forEach((category) => {
category.questions
.sort((a, b) => parseInt(a.idx, 10) - parseInt(b.idx, 10))

Check failure on line 37 in src/screens/Scans/QuestionPage.tsx

View workflow job for this annotation

GitHub Actions / check

Assignment of mutated arrays is forbidden
.forEach((question) => {
parsedQuestions.push(question);
});
});
}

const fetchQuestions = (currentId: string) => {
const currentIndex = parsedQuestions.findIndex(
(q) => q.id === currentId,
);

const indexes = [
currentIndex - 1,
currentIndex,
currentIndex + 1,
currentIndex + 2,
currentIndex + 3,
currentIndex + 4,
];

const ids: string[] = [];

indexes.forEach((index) => {
if (parsedQuestions.length === 0) {
if (index >= 0) {
ids.push(index.toString());
}
return;
}

const question = parsedQuestions.find(
(q) => q.id === index.toString(),
);

if (question && !questionCache.find((q) => q.id === question.id)) {
ids.push(question.id);
}
});

if (ids.length === 0) return;

fetchScanQuestionRange(ids)
.then((data: ScanQuestion[]) => {
if (!data) return;

const newQuestionCache = [...questionCache];
data.forEach((q) => {
if (!newQuestionCache.find((qc) => qc.id === q.id)) {
newQuestionCache.push(q);
}
});
setQuestionCache(newQuestionCache);

if (currentQuestion === undefined) {
setCurrentQuestion(data.find((q) => q.id === currentId));
}
})
.catch((error) => {
throw error;
});
};

const firstId = parsedQuestions[0]?.id;
const {
data: firstQuestionData,
// isLoading: firstQuestionIsLoading,
// error: firstQuestionError,
} = useScanQuestionRange([firstId]);

if (firstQuestionData && questionCache.length === 0) {
setQuestionCache(firstQuestionData);
setCurrentQuestion(firstQuestionData[0]);
fetchQuestions(firstId);
}

if (parsedQuestions.length > 0 && questions.length === 0) {
setQuestions(parsedQuestions);
setCurrentQuestionIndex(parseInt(parsedQuestions[0].id, 10));
}

const showNextQuestion = () => {
const nextIndex = currentQuestionIndex + 1;
showQuestion(nextIndex);
};

const showPreviousQuestion = () => {
const previousIndex = currentQuestionIndex - 1;
showQuestion(previousIndex);
};

const showQuestion = (index: number) => {
const maxIndex = parsedQuestions.length;

if (index < 1) {
index = 1;
}

if (index > maxIndex) {
index = maxIndex;
}

setCurrentQuestionIndex(index);
setCurrentQuestion(
questionCache.find((q) => q.id === index.toString()),
);

if (!parsedQuestions[index]) return;

try {
fetchQuestions(parsedQuestions[index].id);
} catch (error) {
console.log(error);

Check warning on line 149 in src/screens/Scans/QuestionPage.tsx

View workflow job for this annotation

GitHub Actions / check

Unexpected console statement
fetchQuestions(parsedQuestions[index].id);
}
};

const getProgress = () => {
const maxIndex = parsedQuestions.length;
const currentIndex = currentQuestionIndex;

return currentIndex / maxIndex;
};

return (
<View>
<ProgressBar progress={getProgress()} />
<Text>Question: {currentQuestion?.text}</Text>
<Text>Description: {currentQuestion?.description}</Text>
<Button onPress={showPreviousQuestion}>
<Text>Previous</Text>
</Button>
<Button onPress={showNextQuestion}>
<Text>Next</Text>
</Button>
</View>
);
}
26 changes: 26 additions & 0 deletions src/types/Scan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export type Scan = {
id: string;
name: string;
description: string;
content: string;
scanType: string;
difficulty: string;
imageUrl: any;
categories: Category[];
};

type Category = {
id: string;
idx: string;
name: string;
description: string;
questions: ScanQuestion[];
};

export type ScanQuestion = {
id: string;
idx: string;
categoryId?: string;
text?: string;
description?: string;
};

0 comments on commit d8083d2

Please sign in to comment.