generated from dwd/boilarplate-remix-tailwind-antd
master
parent
9c7a9882ed
commit
f11d95adcd
|
@ -0,0 +1,143 @@
|
||||||
|
import React, { useState, useEffect, FormEvent } from 'react';
|
||||||
|
import { Button, Modal, Spin } from 'antd';
|
||||||
|
|
||||||
|
interface QuizModule {
|
||||||
|
moduleId: string;
|
||||||
|
moduleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const [question, setQuestion] = useState('');
|
||||||
|
const [option1, setOption1] = useState('');
|
||||||
|
const [option2, setOption2 ] = useState('');
|
||||||
|
const [option3, setOption3 ] = useState('');
|
||||||
|
const [option4, setOption4 ] = useState('');
|
||||||
|
const [moduleId, setModuleId] = useState('');
|
||||||
|
const [correctAnswer, setCorrectAnswer] = useState('');
|
||||||
|
|
||||||
|
const [moduleList, setModuleList] = useState<QuizModule[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`https://api.teachertrainingkolkata.in/api/quiz-module-list`)
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
setModuleList(data);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('An error occurred', error);
|
||||||
|
setError(error);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleModuleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const data = { question, option1, option2, option3, option4, correctAnswer, moduleId };
|
||||||
|
setSubmitLoading(true);
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://api.teachertrainingkolkata.in/api/create-question`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network Response not ok');
|
||||||
|
}
|
||||||
|
const result = await response.json();
|
||||||
|
// console.log('Success', result);
|
||||||
|
setOpen(false); // Close the modal on successful submission
|
||||||
|
// Optionally, refresh the quiz list here
|
||||||
|
} catch (error) {
|
||||||
|
// console.error('Error', error);
|
||||||
|
} finally {
|
||||||
|
setSubmitLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const showLoading = () => {
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <Spin size="large" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <div>Error: {error.message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button type="primary" onClick={showLoading}>New Question</Button>
|
||||||
|
<Modal title="Add New Question" centered footer={false} open={open} onCancel={() => setOpen(false)}>
|
||||||
|
{submitLoading ? (
|
||||||
|
<Spin size="large" />
|
||||||
|
) : (
|
||||||
|
<div className='container mx-auto px-4'>
|
||||||
|
<form onSubmit={handleModuleSubmit} className='flex flex-col'>
|
||||||
|
<div className='flex flex-col mb-4'>
|
||||||
|
<label htmlFor="question">Question:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={question} onChange={(e) => setQuestion(e.target.value)} type="text" name='question' id='question'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col mb-4'>
|
||||||
|
<label htmlFor="option1">Option 1:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={option1} onChange={(e) => setOption1(e.target.value)} type="text" name='option1' id='option1'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="option2">Option 2:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={option2} onChange={(e) => setOption2(e.target.value)} type="text" name='option2' id='option2'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="option3">Option 3:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={option3} onChange={(e) => setOption3(e.target.value)} type="text" name='option3' id='option3'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="option4">Option 4:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={option4} onChange={(e) => setOption4(e.target.value)} type="text" name='option4' id='option4'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col' >
|
||||||
|
<label htmlFor="option4">Correct Answer:</label>
|
||||||
|
<select value={correctAnswer} onChange={(e) => setCorrectAnswer(e.target.value)} name="correctAnswer" id="correctAnswer" className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2'>
|
||||||
|
<option value="">-Select-</option>
|
||||||
|
<option value="option1">Option 1</option>
|
||||||
|
<option value="option2">Option 2</option>
|
||||||
|
<option value="option3">Option 3</option>
|
||||||
|
<option value="option4">Option 4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="moduleId">Module ID:</label>
|
||||||
|
<select className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' name="moduleId" id="moduleId" value={moduleId} onChange={(e) => setModuleId(e.target.value)}>
|
||||||
|
<option value="">-Select-</option>
|
||||||
|
{
|
||||||
|
moduleList.map((module => (
|
||||||
|
<option key={module.moduleId} value={module.moduleId}>{module.moduleName}</option>
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button className='bg-[#000] py-2.5 text-[#FFF] rounded-[10px]' type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
|
// quizList
|
|
@ -0,0 +1,16 @@
|
||||||
|
export default function Index(){
|
||||||
|
return(
|
||||||
|
<div className="">
|
||||||
|
<section className="container-fluid bg-[#000] text-[#FFF] py-3">
|
||||||
|
<div className="flex flex-row justify-center space-x-10 place-items-center">
|
||||||
|
<a href="">New Module</a>
|
||||||
|
<a href="">New Quiz</a>
|
||||||
|
<a href="">New Quiz Question</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section className="container mx-auto px-4">
|
||||||
|
<div className="flex"></div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
interface QuizModule {
|
||||||
|
moduleName: string;
|
||||||
|
type: string;
|
||||||
|
moduleId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AdminIndex() {
|
||||||
|
const [moduleList, setModuleList] = useState<QuizModule[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`https://api.teachertrainingkolkata.in/api/quiz-module-list`)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log(data);
|
||||||
|
setModuleList(data);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('An error occurred', error);
|
||||||
|
setError(error);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []); // Dependency array to run the effect only once on mount
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <div>Loading...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <div>Error: {error.message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<section className="container mx-auto px-4">
|
||||||
|
<div>
|
||||||
|
<table className='w-full'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Module ID</th>
|
||||||
|
<th>Module Name</th>
|
||||||
|
<th>Module Type</th>
|
||||||
|
<th className=''>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{moduleList.map(module => (
|
||||||
|
<tr key={module.moduleId}>
|
||||||
|
<td>{module.moduleId}</td>
|
||||||
|
<td>{module.moduleName}</td>
|
||||||
|
<td>{module.type}</td>
|
||||||
|
<td>
|
||||||
|
<div className='flex flex-row space-x-2'>
|
||||||
|
<a href={`/admin/edit-module?id=${module.moduleId}`}>Edit</a>
|
||||||
|
<span>|</span>
|
||||||
|
<a href="">Delete</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
import React, { useState, FormEvent } from 'react';
|
||||||
|
import { Button, Modal, Spin } from 'antd';
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const [moduleName, setModuleName] = useState('');
|
||||||
|
const [moduleType, setModuleType] = useState('');
|
||||||
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const handleModuleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const data = {
|
||||||
|
moduleName,
|
||||||
|
moduleType,
|
||||||
|
};
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://api.teachertrainingkolkata.in/api/create-module`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network Response not ok');
|
||||||
|
}
|
||||||
|
const result = await response.json();
|
||||||
|
console.log('Success', result);
|
||||||
|
setOpen(false); // Close the modal on successful submission
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error', error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const showLoading = () => {
|
||||||
|
setOpen(true);
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
// Simple loading mock. You should add cleanup logic in the real world.
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button type="primary" onClick={showLoading}>New Module</Button>
|
||||||
|
<Modal
|
||||||
|
title="Loading Modal" centered
|
||||||
|
footer={false}
|
||||||
|
open={open}
|
||||||
|
onCancel={() => setOpen(false)}
|
||||||
|
>
|
||||||
|
{loading ? (
|
||||||
|
<Spin size="large" />
|
||||||
|
) : (
|
||||||
|
<div className='container mx-auto px-4'>
|
||||||
|
<form onSubmit={handleModuleSubmit} className='flex flex-col'>
|
||||||
|
<div className='flex flex-col mb-4'>
|
||||||
|
<label htmlFor="moduleName">Module Name:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={moduleName} onChange={(e) => setModuleName(e.target.value)} type="text" name='moduleName' id='moduleName' />
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="moduleType">Module Type:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={moduleType} onChange={(e) => setModuleType(e.target.value)} type="text" name='moduleType' id='moduleType' />
|
||||||
|
</div><br />
|
||||||
|
<button className='bg-[#000] py-2.5 text-[#FFF] rounded-[10px]' type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
|
@ -0,0 +1,137 @@
|
||||||
|
import React, { useState, useEffect, FormEvent } from 'react';
|
||||||
|
import { Button, Modal, Spin } from 'antd';
|
||||||
|
|
||||||
|
interface QuizModule {
|
||||||
|
moduleId: string;
|
||||||
|
moduleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const [moduleList, setModuleList] = useState<QuizModule[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
const [quizName, setQuizName] = useState('');
|
||||||
|
const [totalQuestion, settotalQuestion] = useState('');
|
||||||
|
const [attendance, setAttendance] = useState('');
|
||||||
|
const [internalMarks, setInternalMarks] = useState('');
|
||||||
|
const [moduleId, setModuleId] = useState('');
|
||||||
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`https://api.teachertrainingkolkata.in/api/quiz-module-list`)
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
setModuleList(data);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('An error occurred', error);
|
||||||
|
setError(error);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleModuleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const data = {
|
||||||
|
quizName,
|
||||||
|
totalQuestion,
|
||||||
|
attendance,
|
||||||
|
internalMarks,
|
||||||
|
moduleId,
|
||||||
|
|
||||||
|
};
|
||||||
|
setSubmitLoading(true);
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://api.teachertrainingkolkata.in/api/create-quiz`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network Response not ok');
|
||||||
|
}
|
||||||
|
const result = await response.json();
|
||||||
|
console.log('Success', result);
|
||||||
|
setOpen(false); // Close the modal on successful submission
|
||||||
|
// Optionally, refresh the quiz list here
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error', error);
|
||||||
|
} finally {
|
||||||
|
setSubmitLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const showLoading = () => {
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <Spin size="large" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <div>Error: {error.message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button type="primary" onClick={showLoading}>New Module</Button>
|
||||||
|
<Modal title="Loading Modal" centered footer={false} open={open} onCancel={() => setOpen(false)}>
|
||||||
|
{submitLoading ? (
|
||||||
|
<Spin size="large" />
|
||||||
|
) : (
|
||||||
|
<div className='container mx-auto px-4'>
|
||||||
|
<form onSubmit={handleModuleSubmit} className='flex flex-col'>
|
||||||
|
<div className='flex flex-col mb-4'>
|
||||||
|
<label htmlFor="quizName">Quiz Name:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={quizName} onChange={(e) => setQuizName(e.target.value)} type="text" name='quizName' id='quizName'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col mb-4'>
|
||||||
|
<label htmlFor="totalQuestion">Total Question:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={totalQuestion} onChange={(e) => settotalQuestion(e.target.value)} type="text" name='totalQuestion' id='totalQuestion'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="attendance">Attendance:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={attendance} onChange={(e) => setAttendance(e.target.value)} type="text" name='attendance' id='attendance'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="attendance">Attendance:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={attendance} onChange={(e) => setAttendance(e.target.value)} type="text" name='attendance' id='attendance'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="internalMarks">Internal Marks:</label>
|
||||||
|
<input className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' value={internalMarks} onChange={(e) => setInternalMarks(e.target.value)} type="text" name='internalMarks' id='internalMarks'/>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<label htmlFor="moduleId">Module ID:</label>
|
||||||
|
<select className='border-[1px] border-[#CFCFCF] focus:outline-none focus:border-[#EF7A0C] rounded-[8px] p-2' name="moduleId" id="moduleId" value={moduleId} onChange={(e) => setModuleId(e.target.value)}>
|
||||||
|
{
|
||||||
|
moduleList.map((module => (
|
||||||
|
<option key={module.moduleId} value={module.moduleId}>{module.moduleName}</option>
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<input type="text" name='moduleId' id='moduleId'/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<button className='bg-[#000] py-2.5 text-[#FFF] rounded-[10px]' type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default App;
|
||||||
|
// quizList
|
|
@ -0,0 +1,99 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
interface QuizModule {
|
||||||
|
questionId: string;
|
||||||
|
questionText: string;
|
||||||
|
option1: string;
|
||||||
|
option2: string;
|
||||||
|
option3: string;
|
||||||
|
option4: string;
|
||||||
|
correctAnswer: string;
|
||||||
|
moduleId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AdminIndex() {
|
||||||
|
const [questionList, setQuestionList] = useState<QuizModule[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`https://api.teachertrainingkolkata.in/api/question-list`)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log(data);
|
||||||
|
setQuestionList(data);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('An error occurred', error);
|
||||||
|
setError(error);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []); // Dependency array to run the effect only once on mount
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <div>Loading...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <div>Error: {error.message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<section className="container mx-auto px-4">
|
||||||
|
<div>
|
||||||
|
<table className='w-full'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Question ID</th>
|
||||||
|
<th>Question</th>
|
||||||
|
<th>Option 1</th>
|
||||||
|
<th>Option 2</th>
|
||||||
|
<th>Option 3</th>
|
||||||
|
<th>Option 4</th>
|
||||||
|
<th>Correct Answer</th>
|
||||||
|
<th>Module ID</th>
|
||||||
|
<th className=''>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{questionList.map(question => (
|
||||||
|
<tr key={question.questionId}>
|
||||||
|
<td>{question.questionId}</td>
|
||||||
|
<td>{question.questionText}</td>
|
||||||
|
<td>{question.option1}</td>
|
||||||
|
<td>{question.option2}</td>
|
||||||
|
<td>{question.option3}</td>
|
||||||
|
<td>{question.option4}</td>
|
||||||
|
<td>{question.correctAnswer}</td>
|
||||||
|
<td>{question.moduleId}</td>
|
||||||
|
<td>
|
||||||
|
<div className='flex flex-row space-x-2'>
|
||||||
|
<a href={`/admin/edit-question?id=${question.questionId}`}>Edit</a>
|
||||||
|
<span>|</span>
|
||||||
|
<a href="">Delete</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
interface QuizModule {
|
||||||
|
quizName: string;
|
||||||
|
quizId: string;
|
||||||
|
totalQuestion: string;
|
||||||
|
internalMarks: string;
|
||||||
|
attendance: string;
|
||||||
|
moduleId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AdminIndex() {
|
||||||
|
const [quizList, setQuizList] = useState<QuizModule[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`https://api.teachertrainingkolkata.in/api/quiz-list`)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log(data);
|
||||||
|
setQuizList(data);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('An error occurred', error);
|
||||||
|
setError(error);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []); // Dependency array to run the effect only once on mount
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <div>Loading...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <div>Error: {error.message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<section className="container mx-auto px-4">
|
||||||
|
<div>
|
||||||
|
<table className='w-full'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Quiz ID</th>
|
||||||
|
<th>Quiz Name</th>
|
||||||
|
<th>Total Question</th>
|
||||||
|
<th>internalMarks</th>
|
||||||
|
<th>Attendance</th>
|
||||||
|
<th>Module ID</th>
|
||||||
|
<th className=''>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{quizList.map(quiz => (
|
||||||
|
<tr key={quiz.quizId}>
|
||||||
|
<td>{quiz.quizId}</td>
|
||||||
|
<td>{quiz.quizName}</td>
|
||||||
|
<td>{quiz.totalQuestion}</td>
|
||||||
|
<td>{quiz.internalMarks}</td>
|
||||||
|
<td>{quiz.attendance}</td>
|
||||||
|
<td>{quiz.moduleId}</td>
|
||||||
|
<td>
|
||||||
|
<div className='flex flex-row space-x-2'>
|
||||||
|
<a href={`/admin/edit-quiz?id=${quiz.quizId}`}>Edit</a>
|
||||||
|
<span>|</span>
|
||||||
|
<a href="">Delete</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import AdminNav from '~/components/AdminNav'
|
||||||
|
|
||||||
|
export default function AdminIndex(){
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<AdminNav />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import AdminNav from '~/components/AdminNav';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import ModuleList from '~/components/ModuleList';
|
||||||
|
import NewModule from '~/components/NewModule';
|
||||||
|
|
||||||
|
|
||||||
|
export default function AdminIndex(){
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<AdminNav />
|
||||||
|
<NewModule />
|
||||||
|
<div>
|
||||||
|
<ModuleList />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import AdminNav from '~/components/AdminNav';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import NewQuestion from '~/components/AddQuestion'
|
||||||
|
import QuestionList from '~/components/QuestionList'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function AdminIndex(){
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<AdminNav />
|
||||||
|
<div>
|
||||||
|
<NewQuestion />
|
||||||
|
</div>
|
||||||
|
<QuestionList />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import AdminNav from '~/components/AdminNav';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import QuizList from '~/components/QuizList';
|
||||||
|
import NewQuiz from '~/components/NewQuiz';
|
||||||
|
|
||||||
|
|
||||||
|
export default function AdminIndex(){
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<AdminNav />
|
||||||
|
<NewQuiz />
|
||||||
|
<div>
|
||||||
|
<QuizList />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue