Compare commits

...

18 Commits

Author SHA1 Message Date
Suvodip bcae7c673f s1 2024-08-13 18:50:45 +05:30
Suvodip 5ae9d77c5a s1 2024-08-10 13:57:57 +05:30
Suvodip 95628fe09b s3 2024-08-09 21:31:50 +05:30
Suvodip ec099bf3ab s1 2024-08-07 21:55:33 +05:30
Suvodip 2512a918fb s1 2024-08-07 11:13:48 +05:30
Suvodip d049614691 s1 2024-08-05 20:06:44 +05:30
Suvodip f45cb49419 s1 2024-08-05 12:23:01 +05:30
Suvodip 768a1fc0d9 s1 2024-08-02 18:19:11 +05:30
Suvodip c1d6350b2b quiz 2024-08-01 13:45:25 +05:30
Suvodip 3809500839 s1 2024-07-31 22:04:10 +05:30
Suvodip f11d95adcd s1 2024-07-31 20:06:47 +05:30
Suvodip 9c7a9882ed s1 2024-07-30 20:59:12 +05:30
Suvodip f65b67b2a5 s1 2024-07-30 13:00:26 +05:30
Suvodip c665a27db8 dynamic data 2024-07-29 21:45:32 +05:30
Suvodip db1be21da7 work on classmate-directory page 2024-07-29 17:34:42 +05:30
Suvodip 109c1a598f s1 2024-07-27 18:54:03 +05:30
Suvodip 932b734918 s1 2024-07-27 13:11:45 +05:30
Suvodip 69ad64df28 s1 2024-07-26 20:41:32 +05:30
117 changed files with 5434 additions and 900 deletions

View File

@ -0,0 +1,166 @@
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('');
let moduleList = [
{
moduleId : "1",
moduleName : "Module Name - 1"
},
{
moduleId : "2",
moduleName : "Module Name - 2"
},
{
moduleId : "3",
moduleName : "Module Name - 3"
},
{
moduleId : "4",
moduleName : "Module Name - 4"
},
{
moduleId : "5",
moduleName : "Module Name - 5"
}
]
// 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(`http://localhost:5174/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(`http://localhost:5174/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

View File

@ -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>
)
}

View File

@ -0,0 +1,63 @@
import React from 'react';
import { Image } from 'antd';
import Index from './AdminNav';
const fallBackImage = "data:image/png;base64,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";
let artCraftImage = [
{
id: "1",
type: "art&craft",
img: "/assets/aimage1.jpg",
},
{
id: "2",
type: "art&craft",
img: "/assets/aimage2.jpg",
},
{
id: "3",
type: "art&craft",
img: "/assets/aimage3.jpg",
},
{
id: "4",
type: "art&craft",
img: "/assets/aimage4.jpg",
},
{
id: "5",
type: "art&craft",
img: "/assets/aimage5.jpg",
},
{
id: "6",
type: "art&craft",
img: "/assets/aimage2.jpg",
},
{
id: "7",
type: "art&craft",
img: "/assets/aimage4.jpg",
}
]
const App: React.FC = () => (
<Image.PreviewGroup fallback={fallBackImage} preview={{onChange: (current, prev) => console.log(`current index: ${current}, prev index: ${prev}`),}}>
<div className=''>
<section className='container mx-auto px-4'>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 overflow-hidden mt-10'>
{
artCraftImage.map((data) => (
// <div className='grid grid-cols-1 lg:grid-cols-3' key={data.id}></div>
<Image placeholder={true} key={data.id} width={288} height={257} src={data.img}
/>
))
}
</div>
</section>
</div>
</Image.PreviewGroup>
);
export default App;

View File

@ -0,0 +1,89 @@
import React from 'react';
import { Image } from 'antd';
import Index from './AdminNav';
const fallBackImage = "data:image/png;base64,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";
let artCraftImage = [
{
id: "1",
type: "gk&groupactivity",
img: "/assets/gimage1.jpg"
},
{
id: "2",
type: "gk&groupactivity",
img: "/assets/gimage2.jpg"
},
{
id: "3",
type: "gk&groupactivity",
img: "/assets/gimage3.jpg"
},
{
id: "4",
type: "gk&groupactivity",
img: "/assets/gimage4.jpg"
},
{
id: "5",
type: "gk&groupactivity",
img: "/assets/gimage5.jpg"
},
{
id: "6",
type: "gk&groupactivity",
img: "/assets/gimage6.jpg"
},
{
id: "7",
type: "gk&groupactivity",
img: "/assets/gimage7.jpg"
},
{
id: "8",
type: "gk&groupactivity",
img: "/assets/gimage8.jpg"
},
{
id: "9",
type: "gk&groupactivity",
img: "/assets/gimage9.jpg"
},
{
id: "10",
type: "gk&groupactivity",
img: "/assets/gimage10.jpg"
},
{
id: "11",
type: "gk&groupactivity",
img: "/assets/gimage11.jpg"
},
{
id: "12",
type: "gk&groupactivity",
img: "/assets/gimage12.jpg"
}
]
const App: React.FC = () => (
<Image.PreviewGroup fallback={fallBackImage} preview={{onChange: (current, prev) => console.log(`current index: ${current}, prev index: ${prev}`),}}>
<div className=''>
<section className='container mx-auto px-4'>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 overflow-hidden mt-10'>
{
artCraftImage.map((data) => (
// <div className='grid grid-cols-1 lg:grid-cols-3' key={data.id}></div>
<Image placeholder={true} key={data.id} width={288} height={257} src={data.img}
/>
))
}
</div>
</section>
</div>
</Image.PreviewGroup>
);
export default App;

View File

@ -0,0 +1,41 @@
let albumsData = [
{
id : "1",
type : "Art & Craft Album",
img : "/assets/athumbnail1.jpg",
url : "/albums/art-&-craft"
},
{
id : "2",
type : "GK & Group Activity",
img : "/assets/athumbnail2.jpg",
url : "/albums/gk-&-group-activity"
},
{
id : "3",
type : "Language & Maths",
img : "/assets/athumbnail3.jpg",
url : "/albums/language-&-maths"
}
]
export default function AlbumIndex(){
return(
<div>
<section className="container mx-auto px-4">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 p-8">
{
albumsData.map((data) => (
<a href={data.url} key={data.id} className="rounded-[10px] border-[1px] border-[#D4D4D4] relative inline-block">
<img className="w-full rounded-[10px]" src={data.img} alt="" />
<h2 className="absolute bottom-6 left-6 text-[24px] font-[700] text-[#FFF] underline">{data.type}</h2>
</a>
))
}
<div></div>
</div>
</section>
</div>
)
}

View File

@ -0,0 +1,84 @@
import React from 'react';
import { Image } from 'antd';
import Index from './AdminNav';
const fallBackImage = "data:image/png;base64,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";
let artCraftImage = [
{
id: "1",
type: "language&maths",
img: "/assets/limage1.jpg"
},
{
id: "2",
type: "language&maths",
img: "/assets/limage2.jpg"
},
{
id: "3",
type: "language&maths",
img: "/assets/limage3.jpg"
},
{
id: "4",
type: "language&maths",
img: "/assets/limage4.jpg"
},
{
id: "5",
type: "language&maths",
img: "/assets/limage5.jpg"
},
{
id: "6",
type: "language&maths",
img: "/assets/limage6.jpg"
},
{
id: "7",
type: "language&maths",
img: "/assets/limage7.jpg"
},
{
id: "8",
type: "language&maths",
img: "/assets/limage8.jpg"
},
{
id: "9",
type: "language&maths",
img: "/assets/limage9.jpg"
},
{
id: "10",
type: "language&maths",
img: "/assets/limage10.jpg"
},
{
id: "11",
type: "language&maths",
img: "/assets/limage11.jpg"
}
]
const App: React.FC = () => (
<Image.PreviewGroup fallback={fallBackImage} preview={{onChange: (current, prev) => console.log(`current index: ${current}, prev index: ${prev}`),}}>
<div className=''>
<section className='container mx-auto px-4'>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 overflow-hidden mt-10'>
{
artCraftImage.map((data) => (
// <div className='grid grid-cols-1 lg:grid-cols-3' key={data.id}></div>
<Image placeholder={true} key={data.id} width={288} height={257} src={data.img}
/>
))
}
</div>
</section>
</div>
</Image.PreviewGroup>
);
export default App;

View File

@ -0,0 +1,61 @@
import React, { useEffect, useState } from 'react';
interface Performer {
id: number;
name: string;
avatar: string;
program: string;
type: string;
}
export default function classMatesDirectory() {
const [classmatesData, setData] = useState<Performer[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch('http://localhost:5174/api/class-mates')
.then(res => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setError(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return (
<div className=''>
<p className='text-[18px] font-[700] text-[#525252] border-b-[1px] border-b-[#CFCFCF] py-5 pl-5 container-fluid'>
<span>Your Classmates </span>&nbsp; | &nbsp;<span>Graduate Program</span>
</p>
<div className='container mx-auto grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3 gap-6 place-items-center p-6'>
{classmatesData.map(data => (
<div key={data.id} className='relative flex flex-col justify-center items-center shadow-lg w-full rounded-[10px] py-8 overflow-hidden' style={{ background: 'transparent' }}>
<div className='absolute top-0 left-0 w-full h-1/2' style={{ backgroundImage: `url('${data.avatar}')`, backgroundRepeat: 'no-repeat', backgroundSize: 'cover', backgroundPosition: 'center', filter: 'blur(8px)'}}></div>
<div className='absolute bottom-0 left-0 w-full h-1/2 bg-[#FFF] '></div><br /><br />
<img className='w-[60px] h-[60px] border-[4px] border-[#FFF] rounded-full z-10' src={data.avatar} alt="" />
<p className='z-10 text-[16px] font-[700] text-[]'>{data.name}</p>
<p className='z-10 text-[12px] font-[500] text-[#6E6E6E]'>
<span>{data.program}</span> | <span>{data.type}</span>
</p>
</div>
))}
</div>
</div>
);
}

View File

@ -0,0 +1,155 @@
import React from "react";
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined } from '@ant-design/icons';
import { Layout, Menu, theme, Button, Modal, MenuProps } from 'antd';
import { Dropdown, Space } from 'antd';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { Calendar, Col, Row, Typography } from 'antd';
import type { CalendarProps } from 'antd';
import type { Dayjs } from 'dayjs';
import dayLocaleData from 'dayjs/plugin/localeData';
import { Content } from "antd/es/layout/layout";
import '../../public/assets/left_side_nav.css';
dayjs.extend(dayLocaleData);
const schedule = [
{ time: '9 AM', title: 'Lorem Ipsum', details: '9 - 10 AM', borderColor: 'indigo-600', bgColor: 'bg-blue-200' },
{ time: '10 AM', title: 'Lorem Ipsum', details: '10 - 11 AM', borderColor: 'orange-600', bgColor: 'bg-blue-200' },
{ time: '11 AM', title: '', details: '', borderColor: '', bgColor: '' },
{ time: '12 PM', title: 'Lorem Ipsum dolor sit', details: '11:30 AM - 12:30 PM', borderColor: 'indigo-600', bgColor: '' },
{ time: '1 PM', title: 'Lorem Ipsum', details: '11:30 AM - 12:30 PM', borderColor: 'green-600', bgColor: '' },
{ time: '2 PM', title: 'Lorem Ipsum dolor sit', details: '11:30 AM - 12:30 PM', borderColor: 'red-700', bgColor: '' },
{ time: '3 PM', title: 'Lorem Ipsum dolor sit', details: '11 AM - 12:30 PM', borderColor: 'blue-700', bgColor: '' },
{ time: '4 PM', title: 'Lorem Ipsum', details: '11:30 AM - 12:30 PM', borderColor: 'sky-700', bgColor: 'bg-blue-200' },
{ time: '5 PM', title: '', details: '', borderColor: '', bgColor: '' }
];
const App: React.FC = () => {
const { token } = theme.useToken();
const onPanelChange = (value: Dayjs, mode: CalendarProps<Dayjs>['mode']) => {
console.log(value.format('YYYY-MM-DD'), mode);
};
const wrapperStyle: React.CSSProperties = {
width: 320,
border: `1px solid ${token.colorBorderSecondary}`,
borderRadius: token.borderRadiusLG,
padding: 16,
};
const headerStyle: React.CSSProperties = {
display: 'flex',
justifyContent: 'space-around',
alignItems: 'center',
// marginBottom: 16,
backgroundColor: '#0752bc',
height: 47,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
};
const titleStyle: React.CSSProperties = {
fontSize: 14,
fontWeight: 'bold',
color: '#fff',
};
const navButtonStyle: React.CSSProperties = {
cursor: 'pointer',
fontSize: 16,
};
return (
<>
<div className="container mx-auto">
<div className="grid gap-4 sm:grid-cols-1 md:grid-cols-[350px_1fr]">
<div className=" p-4">
<div className="grid grid-rows-2">
<div className="mb-4 bg-card bg-gray-200 rounded-lg shadow-md border border-zinc-300 dark:bg-card-foreground">
<Calendar
fullscreen={false}
headerRender={({ value, onChange }) => {
const monthFormat = 'MMMM';
const year = value.year();
const month = value.format(monthFormat);
const prevMonth = () => {
const newValue = value.clone().subtract(1, 'month');
onChange(newValue);
};
const nextMonth = () => {
const newValue = value.clone().add(1, 'month');
onChange(newValue);
};
return (
<div style={headerStyle}>
<div className="">
<div style={titleStyle}>{`${month} ${year}`}</div>
</div>
<div className="flex gap-8">
<div style={navButtonStyle} onClick={prevMonth}>{'<'}</div>
<div style={navButtonStyle} onClick={nextMonth}>{'>'}</div>
</div>
</div>
);
}}
onPanelChange={onPanelChange}
/>
</div>
<div className="">
<div className="bg-card h-80 bg-gray-200 rounded-lg shadow-md border border-zinc-300 dark:bg-card-foreground">
<div className="flex justify-around items-center h-12 border-b-2 border-zinc-300 bg-[#0752bc] rounded-t-lg">
{/* <h2 className="text-lg items-center font-semibold text-foreground dark:text-card-foreground">Upcoming Classes</h2> */}
<h2 style={titleStyle}>Upcoming Classes <span>&gt;</span></h2>
</div>
<div className=" ">
<div className="border-b-2 border-zinc-300 pb-12"></div>
<div className="border-b-2 border-zinc-300 pb-12"></div>
<div className="border-b-2 border-zinc-300 pb-12"></div>
<div className="border-b-2 border-zinc-300 pb-12"></div>
</div>
</div>
</div>
</div>
</div>
<div className="p-4 border-l-[1px] py-2 border-[#CFCFCF]">
<div className="xl:col-span-4">
<div className="p-4 bg-background">
<h2 className="text-lg font-semibold mb-4 border-b-[1px] py-2 border-[#CFCFCF]">Today's Schedule</h2>
<div className="space-y-2">
{schedule.map((item, index) => (
<div className="flex" key={index}>
<span className="w-16 text-zinc-700">{item.time}</span>
{item.title ? (
<div className={`flex-1 ${item.bgColor} p-2 border-l-4 border-${item.borderColor} rounded-r-lg`}>
<span>{item.title}</span><br />
<span className="text-sm text-zinc-500">{item.details}</span>
</div>
) : (
<div className="flex-1"></div>
)}
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
</>
)
}
export default App;

View File

@ -0,0 +1,18 @@
export default function Index() {
return (
<div className='relative flex flex-col justify-center items-center shadow-lg w-full rounded-[10px] py-8 overflow-hidden' style={{ background: 'transparent' }}>
<div className='absolute top-0 left-0 w-full h-2/5' style={{ backgroundImage: `url('../../assets/tutor.png')`, backgroundRepeat: 'no-repeat', backgroundSize: 'cover', backgroundPosition: 'center', filter: 'blur(8px)' }}></div>
<div className='absolute bottom-0 left-0 w-full h-3/5' style={{background: 'linear-gradient(101.74deg, #4276C5 0.01%, #26529D 100.18%)'}}></div>
<br /><br />
<img className='w-[115px] h-[115px] border-[5px] border-[#3362AF] rounded-full z-10' src={`../../assets/tutor.png`} alt="Tutor" />
<p className='z-10 text-[30px] font-[700] text-[#FFF]'>Sarah Anderson</p>
<p className='z-10 '>
<span className="text-[14px] font-[700] text-[#EF7A0C]">TUTOR </span>
<span className="text-[#FFF]"> | </span>
<span className="text-[14px] font-[600] text-[#FFF]">Graduate Program</span>
</p>
<div className="z-10 border-b-[1px] border-[#B8B8B8] w-full my-3"></div>
<p className="z-10 text-[12px] font-[600] text-[#fff] text-center">Early Childhood Educator | 3 YRS of Experience</p>
</div>
);
}

View File

@ -0,0 +1,61 @@
import React, { useEffect, useState } from 'react';
interface Performer {
id: number;
title: string;
chapter: string;
img: string;
Program: string;
}
export default function ContinueLearning() {
const [courseData, setData] = useState<Performer[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch('http://localhost:5174/api/continue-learning')
.then(res => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then(data => {
console.log(data)
setData(data);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setError(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return (
<section className='bg-[#FCFCFC]'>
<div className='container mx-auto'>
<h2 className='text-[20px] font-[700] my-4 inline-flex leading-[24px]'>Continue Learning <img src="/assets/right-arrow.svg" alt="" /></h2>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'>
{courseData.map(data=>(
<div key={data.id} className=''>
<img className='w-full rounded-[10px]' src={data.img} alt="" />
<h2 className='text-[16px] font-[700] my-2'>{data.title}</h2>
<p className='text-[14px] font-[500] text-[#6E6E6E]'>
<span>Chapter {data.chapter}</span> &#8226; &nbsp;
<span>{data.Program}</span>
</p>
</div>
))}
</div>
</div>
</section>
)
}

View File

@ -0,0 +1,123 @@
import React, { useState } from 'react';
import { Button, Modal } from 'antd';
import { InboxOutlined } from '@ant-design/icons';
import type { UploadProps } from 'antd';
import { message, Upload } from 'antd';
const { Dragger } = Upload;
const App: React.FC = () => {
const [fileCount, setFileCount] = useState(0);
const [uploadingNumber, setUploadingNumber] = useState(0);
const props: UploadProps = {
name: 'file',
multiple: true,
action: 'https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload',
onChange(info) {
const { status } = info.file;
setFileCount(info.fileList.length); // Update file count whenever files are added or removed
if (status !== 'uploading') {
// console.log(info.file, info.fileList);
}
if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`);
} else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`);
setUploadingNumber(currentFile => currentFile + 1);
}
},
onDrop(e) {
// console.log('Dropped files', e.dataTransfer.files);
setFileCount(e.dataTransfer.files.length); // Update file count on drop
// setUploadingNumber(currentFile => currentFile + 1);
},
};
const [isModalOpen, setIsModalOpen] = useState(false);
const showModal = () => {
setIsModalOpen(true);
};
const handleOk = () => {
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
const customCloseButton = () => {
setIsModalOpen(false);
};
return (
<>
<div>
<section className='container mx-auto px-4'>
<button onClick={showModal}>
<div className='flex flex-col justify-center place-items-center shadow-lg w-[279px] h-[255px] rounded-[8px]'>
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0.351562 19.8796C0.351562 8.9496 9.21156 0.0895996 20.1416 0.0895996C31.0716 0.0895996 39.9316 8.9496 39.9316 19.8796C39.9316 30.8097 31.0716 39.6697 20.1416 39.6697C9.21156 39.6697 0.351562 30.8097 0.351562 19.8796ZM20.1416 4.04761C15.9427 4.04761 11.9157 5.71562 8.94666 8.6847C5.97758 11.6538 4.30957 15.6807 4.30957 19.8796C4.30957 24.0786 5.97758 28.1055 8.94666 31.0746C11.9157 34.0437 15.9427 35.7117 20.1416 35.7117C24.3405 35.7117 28.3675 34.0437 31.3365 31.0746C34.3056 28.1055 35.9736 24.0786 35.9736 19.8796C35.9736 15.6807 34.3056 11.6538 31.3365 8.6847C28.3675 5.71562 24.3405 4.04761 20.1416 4.04761Z" fill="#C4C4C4"/><path d="M22.1187 9.98462C22.1187 9.45975 21.9102 8.95639 21.539 8.58525C21.1679 8.21412 20.6645 8.00562 20.1396 8.00562C19.6148 8.00562 19.1114 8.21412 18.7403 8.58525C18.3691 8.95639 18.1606 9.45975 18.1606 9.98462V17.9006H10.2446C9.71976 17.9006 9.2164 18.1091 8.84526 18.4803C8.47413 18.8514 8.26562 19.3548 8.26562 19.8796C8.26562 20.4045 8.47413 20.9079 8.84526 21.279C9.2164 21.6501 9.71976 21.8586 10.2446 21.8586H18.1606V29.7747C18.1606 30.2995 18.3691 30.8029 18.7403 31.174C19.1114 31.5452 19.6148 31.7537 20.1396 31.7537C20.6645 31.7537 21.1679 31.5452 21.539 31.174C21.9102 30.8029 22.1187 30.2995 22.1187 29.7747V21.8586H30.0347C30.5595 21.8586 31.0629 21.6501 31.434 21.279C31.8052 20.9079 32.0137 20.4045 32.0137 19.8796C32.0137 19.3548 31.8052 18.8514 31.434 18.4803C31.0629 18.1091 30.5595 17.9006 30.0347 17.9006H22.1187V9.98462Z" fill="#C4C4C4"/></svg>
<p className='text-[14px] font-[600] text-[#C4C4C4] mt-2'>Add new file</p>
</div>
</button>
{/* width={771} */}
<Modal footer={null} title="" width={771} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
{/* <button onClick={customCloseButton} className="float-right absolute right-0 2xl:-right-0 -top-30 bg-[#9D9D9D] w-[45px] h-[45px] font-[700] text-[#FFF] text-[20px] rounded-full">&#10005;</button> */}
<div className='flex flex-col space-y-4 max-w-[554px] w-full mx-auto my-[30px]'>
<div className=''>
<Dragger {...props}>
<div className='flex flex-col justify-center place-items-center h-[236px]'>
<svg width="51" height="47" viewBox="0 0 51 47" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M40.8908 12.405C40.3561 9.22791 38.783 6.32847 36.3771 4.12818C33.7038 1.68113 30.2286 0.334229 26.6095 0.334229C23.8128 0.334229 21.0882 1.1362 18.7542 2.64762C16.811 3.90198 15.1967 5.59847 14.0555 7.59312C13.562 7.50059 13.0479 7.44918 12.5338 7.44918C8.16405 7.44918 4.60657 11.0067 4.60657 15.3764C4.60657 15.9419 4.66826 16.4868 4.77108 17.0215C1.94361 19.0778 0.226562 22.3885 0.226562 25.9151C0.226562 28.7632 1.28558 31.529 3.21854 33.719C5.20291 35.9604 7.82475 37.2867 10.6214 37.4409H19.5459C20.317 37.4409 20.9339 36.824 20.9339 36.0529C20.9339 35.2818 20.317 34.6649 19.5459 34.6649H10.7448C6.53954 34.4078 3.00263 30.4083 3.00263 25.9049C3.00263 22.9951 4.56545 20.2808 7.08447 18.8105C7.67053 18.4712 7.91729 17.7617 7.69109 17.1243C7.48546 16.5691 7.38264 15.983 7.38264 15.3558C7.38264 12.5181 9.69602 10.2047 12.5338 10.2047C13.1404 10.2047 13.7367 10.3075 14.292 10.5131C14.9705 10.7599 15.7211 10.4514 16.0296 9.80369C17.9522 5.72185 22.1061 3.08973 26.6197 3.08973C32.6859 3.08973 37.6931 7.63425 38.2689 13.6593C38.3306 14.2865 38.8036 14.7903 39.4205 14.8931C43.9958 15.6746 47.4505 19.9003 47.4505 24.7225C47.4505 29.8325 43.4303 34.2742 38.4746 34.6546H30.8969C30.1258 34.6546 29.5089 35.2715 29.5089 36.0426C29.5089 36.8138 30.1258 37.4307 30.8969 37.4307H38.6288C41.7647 37.2045 44.695 35.765 46.8747 33.3591C49.0442 30.9737 50.2266 27.9098 50.2266 24.7225C50.2163 18.9544 46.2784 13.8238 40.8908 12.405Z" fill="#EF7A0C"/><path d="M33.5573 27.2313C34.1022 26.6863 34.1022 25.8124 33.5573 25.2675L26.2058 17.916C25.9488 17.659 25.5889 17.5048 25.2291 17.5048C24.8692 17.5048 24.5094 17.6487 24.2523 17.916L16.9009 25.2675C16.356 25.8124 16.356 26.6863 16.9009 27.2313C17.1682 27.4986 17.5281 27.6425 17.8776 27.6425C18.2272 27.6425 18.5871 27.5089 18.8544 27.2313L23.841 22.2446V45.1626C23.841 45.9337 24.4579 46.5506 25.2291 46.5506C26.0002 46.5506 26.6171 45.9337 26.6171 45.1626V22.2446L31.6037 27.2313C32.1384 27.7762 33.0123 27.7762 33.5573 27.2313Z" fill="#EF7A0C"/></svg>
<p className="text-[16px] font-[700]">Browse or drop a file here</p>
<p className="text-[12px] font-[400] text-[#676767] mt-2">Supported formats: JPEG, PNG PDF, Word, PPT</p>
</div>
</Dragger>
</div>
{/* <p>{uploadingNumber} / {fileCount}</p> */}
<div className='flex flex-col space-y-3'>
<label className='text-[16px ] font-[600]' htmlFor="title">Title *</label>
<input className='border-[1px] border-[#CFCFCF] rounded-[8px] p-2.5 focus:outline-none' placeholder='Enter Title here' type="text" name="title" id="title" />
</div>
<div className='flex flex-col space-y-3'>
<label className='text-[16px ] font-[600]' htmlFor="subject">Subject *</label>
<select className='border-[1px] border-[#CFCFCF] text-[#9D9D9D] bg-[#fff] rounded-[8px] p-2.5 focus:outline-none' name="subject" id="subject">
<option value="0">Select the Subject here</option>
<option value="Subject-1">Subject-1</option>
<option value="Subject-2">Subject-2</option>
<option value="Subject-3">Subject-3</option>
<option value="Subject-4">Subject-4</option>
</select>
</div>
<div className='flex flex-col space-y-3'>
<label className='text-[16px ] font-[600]' htmlFor="practical-exercise">Practical Exercise *</label>
<select className='border-[1px] border-[#CFCFCF] text-[#9D9D9D] bg-[#fff] rounded-[8px] p-2.5 focus:outline-none' name="practical-exercise" id="practical-exercise">
<option value="0">Choose the practical exercise here</option>
<option value="Practical Exercise-1">Practical Exercise-1</option>
<option value="Practical Exercise-2">Practical Exercise-2</option>
<option value="Practical Exercise-3">Practical Exercise-3</option>
<option value="Practical Exercise-4">Practical Exercise-4</option>
</select>
</div><br /><br /><br />
<div className='flex justify-center'>
<button className='bg-[#000] hover:bg-[#00000030] duration-500 rounded-[8px] text-[#FFF] px-[20px] py-[10px]' type="submit">Upload</button>
</div>
</div>
</Modal>
</section>
</div>
</>
);
};
export default App;

View File

@ -698,7 +698,7 @@ const App: React.FC = () => {
<div className='flex flex-row justify-between place-items-center space-x-2 border-b-[1px] border-[#CFCFCF]'>
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='mx-auto h-[52px] w-[60px] ' src={secondHighestRank.avatar} alt="" />
<img className='mx-auto h-[52px] w-[60px] ' src={`../../assets/${secondHighestRank.avatar}`} alt="" />
<img className='absolute mt-12' src="../../assets/bacth2.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{secondHighestRank.name}</p>
@ -707,7 +707,7 @@ const App: React.FC = () => {
<div className='w-full mx-auto h-[130px] -mt-[42px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='-mt-10' src="../../assets/crown.png" alt="" />
<img className='mx-auto h-[52px] w-[60px]' src={highestRank.avatar} alt="" />
<img className='mx-auto h-[52px] w-[60px]' src={`../../assets/${highestRank.avatar}`} alt="" />
<img className='absolute mt-12' src="../../assets/bacth1.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{highestRank.name}</p>
@ -715,7 +715,7 @@ const App: React.FC = () => {
</div>
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='mx-auto h-[52px] w-[60px]' src={thirdHighestRank.avatar} alt="" />
<img className='mx-auto h-[52px] w-[60px]' src={`../../assets/${thirdHighestRank.avatar}`} alt="" />
<img className='absolute mt-12' src="../../assets/bacth3.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{thirdHighestRank.name}</p>
@ -726,7 +726,7 @@ const App: React.FC = () => {
{sortedData.slice(3).map(data => (
<div key={data.id} className='flex flex-row justify-between place-items-center border-b-[1px] border-[#CFCFCF] p-2 hover:bg-[#FDF2E7] duration-700'>
<p className='text-[11px] font-[700]'># {data.rank}</p>
<img className='w-[35px] h-[35px]' src={data.avatar} alt="" />
<img className='w-[35px] h-[35px]' src={`../../assets/${data.avatar}`} alt="" />
<div>
<p className='text-[14px] font-[700]'>{data.name}</p>
<p className='text-[10px] font-[700] text-[#6E6E6E]'>{data.program}</p>

View File

@ -0,0 +1,61 @@
import React, { useEffect, useState } from 'react';
interface Performer {
id: number;
title: string;
img: string;
challenge: string;
question: string;
}
export default function KnowledgeQuests() {
const [knowledgeData, setData] = useState<Performer[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch('http://localhost:5174/api/knowledge-quests')
.then(res => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setError(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return(
<section className=''>
<h2 className='text-[20px] font-[700] inline-flex p-6'>Knowledge Quests <img src="/assets/right-arrow.svg" alt="" /></h2>
<div className='flex flex-col gap-6'>
{knowledgeData.map(data => (
<div key={data.id} className='flex flex-row justify-between px-6 place-items-center'>
<div className='flex flex-row justify-between gap-6'>
<img src={data.img} alt="" />
<div className='flex flex-col space-y-3'>
<h2 className='text-[16px] font-[700] text-[#000]'>{data.title}</h2>
<p className='text-[14px] font-[600] text-[#525252]'>{data.challenge}</p>
<p className='text-[14px] font-[600] text-[#9D9D9D]'>{data.question}</p>
</div>
</div>
<button className='bg-[#000] text-[#FFF] rounded-[8px] px-16 py-3 h-fit text-[18px] font-[600]'>Start</button>
</div>
))}
</div>
</section>
)
}

View File

@ -0,0 +1,113 @@
import { Tabs } from 'antd';
import '../../public/assets/knowledge-quest.css';
import React, { useEffect, useState } from 'react';
interface Performer {
id: number;
img: string;
title: string;
challenge: string;
question: string;
}
export default function Index() {
const [knowledgeDataAll, setKnowledgeDataAll] = useState<Performer[]>([]);
const [knowledgeCompleted, setKnowledgeCompleted] = useState<Performer[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
const [allResponse, completedResponse] = await Promise.all([
fetch('http://localhost:5174/api/all-assesment'),
fetch('http://localhost:5174/api/complete-assesment')
]);
if (!allResponse.ok || !completedResponse.ok) {
throw new Error('Network response was not ok');
}
const allData = await allResponse.json();
const completedData = await completedResponse.json();
setKnowledgeDataAll(allData);
setKnowledgeCompleted(completedData);
setLoading(false);
} catch (error) {
console.error('Error fetching data:', error);
if (error instanceof Error) {
setError(error);
} else {
setError(new Error('An unexpected error occurred'));
}
setLoading(false);
}
};
fetchData();
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
const tabItems = [
{
key: '1',
label: 'All',
children: (
<div className='flex flex-col gap-6'>
{knowledgeDataAll.map(data => (
<div key={data.id} className='flex flex-col lg:flex-row justify-between px-6 place-items-center'>
<div className='flex flex-row justify-between gap-6'>
<img src={data.img} alt="" />
<div className='flex flex-col space-y-3'>
<h2 className='text-[16px] font-[700] text-[#000]'>{data.title}</h2>
<p className='text-[14px] font-[600] text-[#525252]'>{data.challenge}</p>
<p className='text-[14px] font-[600] text-[#9D9D9D]'>{data.question}</p>
</div>
</div>
<button className='bg-[#000] text-[#FFF] rounded-[8px] px-16 py-3 h-fit text-[18px] font-[600]'>Start</button>
</div>
))}
</div>
),
},
{
key: '2',
label: 'Completed',
children: (
<div className='flex flex-col gap-6'>
{knowledgeCompleted.map(data => (
<div key={data.id} className='flex flex-col lg:flex-row justify-between px-6 place-items-center'>
<div className='flex flex-row justify-between gap-6'>
<img src={data.img} alt="" />
<div className='flex flex-col space-y-3'>
<h2 className='text-[16px] font-[700] text-[#000]'>{data.title}</h2>
<p className='text-[14px] font-[600] text-[#525252]'>{data.challenge}</p>
<p className='text-[14px] font-[600] text-[#9D9D9D]'>{data.question} | 200 people have taken this quiz</p>
<div className='flex flex-col md:flex-row gap-x-20'>
<p className='text-[14px] font-[600]'>Score: 9/10</p>
<p className='text-[14px] font-[600] inline-flex place-items-center'>Earned: 9 &nbsp;<img src="../../assets/points-icon.svg" alt="" /></p>
</div>
</div>
</div>
<a href='#' className='bg-[#000] text-[#FFF] rounded-[8px] px-16 py-3 h-fit text-[18px] font-[600]'>Review</a>
</div>
))}
</div>
),
}
];
return (
<div className=''>
<Tabs defaultActiveKey="1" items={tabItems} />
</div>
);
}

View File

@ -0,0 +1,142 @@
import React, {useState} from 'react';
import {Layout, Menu, theme, Button, Modal, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined} from '@ant-design/icons';
import '../../public/assets/left_side_nav.css';
import AdministrationIcon from '~/components/customIcon/AdministrationIcon';
import MyCoursesIcon from '~/components/customIcon/MyCoursesIcon';
import ExaminationIcon from '~/components/customIcon/ExaminationIcon';
import CommunityIcon from '~/components/customIcon/CommunityIcon';
import NotificationIcon from '~/components/customIcon/NotificationIcon';
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom';
const items2: MenuProps['items'] = [
{
key: '1',
icon: <AdministrationIcon />,
label: (<p className='py-2.5'>&nbsp; Administration</p>),
children: [
{
key: 'administration1',
label: (<a href='/class-shedules'>Class Schedules</a>),
},
{
key: 'administration2',
label: (<a href='/classmate-directory'>Classmate Directory</a>),
},
{
key: 'administration3',
label: (<a href='#'>Qualifications</a>),
},
],
},
{
key: '2',
icon: <MyCoursesIcon />,
label: (<p className='py-2.5'>&nbsp; Courses</p>),
children: [
{
key: 'courses1',
label: (<a href='/mycourse/theory'>Theory</a>),
},
{
key: 'courses2',
label: (<a href='/mycourse/practical'>Practical</a>),
},
{
key: 'courses3',
label: (<a href='/mycourse/albums'>Albums</a>),
},
],
},
{
key: '3',
icon: <ExaminationIcon />,
label: (<p className='py-2.5'>&nbsp; Examinations</p>),
children: [
{
key: 'examinations1',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: 'examinations2',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: 'examinations3',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: '4',
icon: <CommunityIcon />,
label: (<p className='py-2.5'>&nbsp; Community</p>),
children: [
{
key: 'community1',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: 'community2',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: 'community3',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: '5',
icon: <NotificationIcon />,
label: (<p className='py-2.5'>&nbsp; Notifications</p>),
children: [
{
key: 'notifications1',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: 'notifications2',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: 'notifications3',
label: (<a href='#'>Passed Exam</a>),
},
],
},
// getItem('Files', '9', <FileOutlined />),
{
key: 'grp',
label: '',
type: 'group',
style: { marginTop: '100px' },
children: [
{
key: '6', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(SettingOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Settings</h2>)
},
{
key: '7', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(QuestionCircleOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Help & Support</h2>)
},
{
key: '8', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(LogoutOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Logout</h2>)
},
],
},
];
const LeftSideMenu: React.FC = () => {
return(
<Menu className='custom-menu' mode="inline" style={{ height: '100%', borderRight: 0, paddingTop: 30, background: 'transparent'}} items={items2} />
)
}
export default LeftSideMenu;

View File

@ -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(`http://localhost:5174/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>
);
}

View File

@ -0,0 +1,126 @@
import React, { useState } from 'react';
import { Timeline } from 'antd';
interface MaterialItem {
id: number;
material: number;
title: string;
type: string;
time: string;
date: string;
source: string;
}
const materialData: MaterialItem[] = [
{
id: 1,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/3195394/3195394-uhd_2560_1440_25fps.mp4"
},
{
id: 2,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/5538137/5538137-sd_640_360_25fps.mp4"
},
{
id: 3,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Reading Material",
time: "8 mins",
date: "28-01-2024",
source: "https://pdfobject.com/pdf/sample.pdf"
},
{
id: 4,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "MCQ",
time: "5 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/3195394/3195394-uhd_2560_1440_25fps.mp4"
},
{
id: 5,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/5532762/5532762-sd_960_506_25fps.mp4"
},
{
id: 6,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/5538262/5538262-sd_640_360_25fps.mp4"
}
];
const TimelineComponent = () => {
const [selectedItem, setSelectedItem] = useState(materialData[0]);
const handleItemClick = (item : MaterialItem) => {
setSelectedItem(item);
};
const timelineItems = materialData.map((item) => ({
children: (
<div className='p-2' onClick={() => handleItemClick(item)} style={{ cursor: 'pointer', backgroundColor: item.id === selectedItem.id ? '#FFF4EA' : '#FFF'}}>
<p className='text-[12px] font-[600] text-[#6E6E6E]'><span>Material {item.material} </span> | <span>{item.date} </span></p>
<h2 className='text-[18px] font-[700]'>{item.title}</h2>
<p className='text-[14px] font-[600] text-[#EF7A0C]'><span>{item.type}</span> | <span>{item.time}</span></p>
</div>
),
color: item.id === selectedItem.id ? '#EF7A0C' : '#CFCFCF',
dot: item.id === selectedItem.id
? <div className='relative inline-block'>
<span className='' style={{ border: '4px solid #EF7A0C', borderRadius: '50%', display: 'inline-block', width: 32, height: 32 }}></span>
<span className='absolute inset-0 m-auto mt-[10px] h-10 w-10' style={{ backgroundColor: '#EF7A0C', borderRadius: '50%', display: 'inline-block', width: 12, height: 12 }}></span>
</div>
: null,
}));
return (
<div>
<section className='container mx-auto px-4'>
<div className='grid grid-cols-1 md:grid-cols-7 gap-x-8'>
<div className='md:col-span-2 h-screen border-r-[1px] border-r-[#CFCFCF]'>
<div className='mt-[40px]'>
<Timeline items={timelineItems} />
</div>
</div>
<div className='md:col-span-5 '>
<div className='pt-8'>
{selectedItem.type === 'Video' && (
<video autoPlay loop controls src={selectedItem.source} width="100%" muted />
)}
{selectedItem.type === 'Reading Material' && (
<iframe src={selectedItem.source} width="100%" height="500px" />
)}
{selectedItem.type === 'MCQ' && (
<div>
{/* Render MCQ content here */}
</div>
)}
<p className='text-[12px] font-[600] text-[#6E6E6E]'><span>Material {selectedItem.material} </span> | <span>{selectedItem.date} </span></p>
<h2 className='text-[18px] font-[700]'>{selectedItem.title}</h2>
<p className='text-[14px] font-[600] text-[#EF7A0C]'><span>{selectedItem.type}</span> | <span>{selectedItem.time}</span></p>
</div>
</div>
</div>
</section>
</div>
);
};
export default TimelineComponent;

View File

@ -0,0 +1,126 @@
import React, { useState } from 'react';
import { Timeline } from 'antd';
interface MaterialItem {
id: number;
material: number;
title: string;
type: string;
time: string;
date: string;
source: string;
}
const materialData: MaterialItem[] = [
{
id: 1,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/3195394/3195394-uhd_2560_1440_25fps.mp4"
},
{
id: 2,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/5538137/5538137-sd_640_360_25fps.mp4"
},
{
id: 3,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Reading Material",
time: "8 mins",
date: "28-01-2024",
source: "https://pdfobject.com/pdf/sample.pdf"
},
{
id: 4,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "MCQ",
time: "5 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/3195394/3195394-uhd_2560_1440_25fps.mp4"
},
{
id: 5,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/5532762/5532762-sd_960_506_25fps.mp4"
},
{
id: 6,
material: 1,
title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
type: "Video",
time: "30 mins",
date: "28-01-2024",
source: "https://videos.pexels.com/video-files/5538262/5538262-sd_640_360_25fps.mp4"
}
];
const TimelineComponent = () => {
const [selectedItem, setSelectedItem] = useState(materialData[0]);
const handleItemClick = (item : MaterialItem) => {
setSelectedItem(item);
};
const timelineItems = materialData.map((item) => ({
children: (
<div className='p-2' onClick={() => handleItemClick(item)} style={{ cursor: 'pointer', backgroundColor: item.id === selectedItem.id ? '#FFF4EA' : '#FFF'}}>
<p className='text-[12px] font-[600] text-[#6E6E6E]'><span>Material {item.material} </span> | <span>{item.date} </span></p>
<h2 className='text-[18px] font-[700]'>{item.title}</h2>
<p className='text-[14px] font-[600] text-[#EF7A0C]'><span>{item.type}</span> | <span>{item.time}</span></p>
</div>
),
color: item.id === selectedItem.id ? '#EF7A0C' : '#CFCFCF',
dot: item.id === selectedItem.id
? <div className='relative inline-block'>
<span className='' style={{ border: '4px solid #EF7A0C', borderRadius: '50%', display: 'inline-block', width: 32, height: 32 }}></span>
<span className='absolute inset-0 m-auto mt-[10px] h-10 w-10' style={{ backgroundColor: '#EF7A0C', borderRadius: '50%', display: 'inline-block', width: 12, height: 12 }}></span>
</div>
: null,
}));
return (
<div>
<section className='container mx-auto px-4'>
<div className='grid grid-cols-1 md:grid-cols-7 gap-x-8'>
<div className='md:col-span-2 h-screen border-r-[1px] border-r-[#CFCFCF]'>
<div className='mt-[40px]'>
<Timeline items={timelineItems} />
</div>
</div>
<div className='md:col-span-5 '>
<div className='pt-8'>
{selectedItem.type === 'Video' && (
<video autoPlay loop controls src={selectedItem.source} width="100%" muted />
)}
{selectedItem.type === 'Reading Material' && (
<iframe src={selectedItem.source} width="100%" height="500px" />
)}
{selectedItem.type === 'MCQ' && (
<div>
{/* Render MCQ content here */}
</div>
)}
<p className='text-[12px] font-[600] text-[#6E6E6E]'><span>Material {selectedItem.material} </span> | <span>{selectedItem.date} </span></p>
<h2 className='text-[18px] font-[700]'>{selectedItem.title}</h2>
<p className='text-[14px] font-[600] text-[#EF7A0C]'><span>{selectedItem.type}</span> | <span>{selectedItem.time}</span></p>
</div>
</div>
</div>
</section>
</div>
);
};
export default TimelineComponent;

View File

@ -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(`http://localhost:5174/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;

137
app/components/NewQuiz.tsx Normal file
View File

@ -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(`http://localhost:5174/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(`http://localhost:5174/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

View File

@ -0,0 +1,134 @@
type PracticalData = {
id: number;
module: number;
status: number;
time: number;
access: number;
title: string;
description: string;
img: string;
total_marks: string;
};
let practicalData: PracticalData[] = [
{
id: 1,
module: 1,
status: 2,
time: 20,
access: 1,
title: "Life History of Dr. Maria Montessori",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/pimage1.jpg",
total_marks: "50"
},
{
id: 2,
module: 2,
status: 1,
time: 20,
access: 1,
title: "Introduction to Montessori Methods",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/pimage2.jpg",
total_marks: "50"
},
{
id: 3,
module: 3,
status: 0,
time: 20,
access: 0,
title: "Exercises in Practical Life",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/pimage3.jpg",
total_marks: "50"
},
{
id: 1,
module: 1,
status: 0,
time: 20,
access: 0,
title: "Life History of Dr. Maria Montessori",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/pimage1.jpg",
total_marks: "50"
},
{
id: 2,
module: 2,
status: 0,
time: 20,
access: 0,
title: "Introduction to Montessori Methods",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/pimage2.jpg",
total_marks: "50"
},
{
id: 3,
module: 3,
status: 0,
time: 20,
access: 0,
title: "Exercises in Practical Life",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/pimage3.jpg",
total_marks: "50"
}
];
export default function CourseTheory() {
const getStatusText = (status: number): string => {
if (status === 2) return "<p style='color: #218B32; font-weight: 600; font-size: 18px; display: inline-flex;'><img style='margin-right: 8px;' src='/assets/green-tick.svg' />Finished</p>";
if (status === 1) return "<p style='color: #EF7A0C; font-weight: 600; font-size: 18px' >40% Completed</p>";
if (status === 0) return " ";
return "";
}
return(
<div>
<section className="container mx-auto p-4 px-10">
<div className="flex flex-row justify-between place-items-center rounded-[10px] bg-[#FBFBFB] border-[1px] border-[#D1D1D1]">
<div className="flex flex-row h-[107px] place-items-center p-4 space-x-6">
<div className="relative inline-block">
<img className="h-[81px] w-[137px] rounded-[10px]" src="/assets/pimage3.jpg" alt="" />
<button className="absolute inset-0 m-auto h-10 w-10">
<img src="/assets/play.svg" alt="" />
</button>
</div>
<div className="">
<h2 className="tet-[18px] font-[700] text-[#000] w-[328px]">Lorem ipsum dolor sit amet, consectetur adipiscing elit</h2>
<p className="text-[14px] font-[600] text-[#EF7A0C]">
<span> Video</span> &nbsp;|&nbsp;
<span> 30 mins</span>
</p>
</div>
</div>
<div className="pr-4">
<button className="bg-[#000] text-[#FFF] font-[600] px-6 py-2 text-[18px] rounded-[8px]">Continue Learning</button>
</div>
</div>
</section>
<section className="container mx-auto px-4">
<div className="grid grid-cols-1 lg:grid-cols-2 p-6 gap-10 ">
{
practicalData.map((data, index) => (
<div key={index} className={`border-[1px] border-[#218B32] p-3 rounded-[10px] ${data.access === 0 ? 'contrast-[0.3]' : ''} `}>
<img className="w-full rounded-[8px]" src={data.img} alt="" />
<h2 className="text-[18px] font-[700]">{data.title}</h2>
<p className="text-[14px] font-[700] text-[#EF7A0C] py-2"><span>{data.time} mins of Practical</span> </p>
{/* <p className="text-[14px] font-[500] text-[#6E6E6E] pb-6">{data.description}</p> */}
<div className="flex flex-row justify-between place-items-center">
<button disabled={data.access === 0} className={`text-[18px] font-[600] bg-[#000] rounded-[8px] px-[50px] py-2 text-[#fff] ${data.access == 0 ? 'cursor-not-allowed' : ''}`}>{data.access === 0 ? 'Locked' : 'View'}</button>
{/* <div dangerouslySetInnerHTML={{ __html: getStatusText(data.status) }} /> */}
</div>
</div>
))
}
</div>
</section>
</div>
)
}

View File

@ -0,0 +1,190 @@
import React, { useState, useEffect } from 'react';
import { Modal } from 'antd';
interface Question {
questionId: string;
questionText: string;
correctAnswer: string;
options: string[];
}
interface Quiz {
quizId: string;
quizName: string;
internalMarks: string;
attendance: string;
attendQuestion: string;
totalQuestion: string;
questions: Question[];
}
interface Module {
moduleId: string;
type: string;
moduleName: string;
quizzes: Quiz[];
}
export default function Index() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedQuiz, setSelectedQuiz] = useState<Quiz | null>(null);
const [quizModuleData, setQuizModuleData] = useState<Module[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch('http://localhost:5174/api/quiz-module')
.then((res) => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then((data) => {
console.log('Fetched data:', data);
// Extract the modules array from the response
if (data && Array.isArray(data.modules)) {
setQuizModuleData(data.modules);
} else {
setError(new Error('Fetched data is not an array'));
}
setLoading(false);
})
.catch((error) => {
console.error('Error fetching data:', error);
setError(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
const showModal = (quiz: Quiz) => {
setSelectedQuiz(quiz);
setIsModalOpen(true);
};
const handleOk = () => {
setIsModalOpen(false);
setSelectedQuiz(null);
};
const handleCancel = () => {
setIsModalOpen(false);
setSelectedQuiz(null);
};
return (
<section className="">
<div className="flex flex-col">
{quizModuleData.length > 0 ? (
quizModuleData.map((moduleData) => (
<div key={moduleData.moduleId}>
<div className="p-6">
<p className="text-[16px] font-[700] text-[#EF7A0C]">{moduleData.type}</p>
<p className="text-[22px] font-[700]">{moduleData.moduleName}</p>
<p className="text-[14px] font-[600]">3/8 Quizzes Completed </p>
</div>
<div className="flex flex-col">
{moduleData.quizzes.map((quizData) => (
<div onClick={() => showModal(quizData)} className="flex flex-row justify-between place-items-center hover:bg-[#FFF4EA] duration-500 border-b-[1px] border-b-[#CFCFCF] p-6 cursor-pointer" key={quizData.quizId}>
<div className="flex flex-col space-y-2">
<h3 className="text-[20px] font-[700]">
#{quizData.quizId} {quizData.quizName}
</h3>
<p className="text-[16px] font-[700] text-[#6E6E6E]">
<span>Internal Marks: {quizData.internalMarks}</span>
&nbsp;&#8226; &nbsp;
<span>Attendance: {quizData.attendance}</span>
</p>
</div>
<div className="flex flex-row space-x-4">
<p className="bg-[#FFE2C7] p-2 rounded-[8px]">
<span className="text-[32px] font-[700] text-[#EF7A0C]">{quizData.attendQuestion}</span>/
<span className="text-[16px] font-[700] ">{quizData.totalQuestion}</span>
</p>
<img src="/assets/right-arrow.svg" alt="" />
</div>
</div>
))}
</div>
</div>
))
) : (
<div>No quiz modules available.</div>
)}
</div>
{selectedQuiz && (
<Modal title={selectedQuiz.quizName} open={isModalOpen} onOk={handleOk} onCancel={handleCancel} width={1000}>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 border-b-[1px] border-b-[#CFCFCF]">
<div className="flex justify-center place-items-center border-r-[1px] border-[#CFCFCF] my-3">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/calendar.svg" alt="" />
</div>
<div className="flex flex-col">
<p className="text-[20px] font-[800]">18/10</p>
<p className="text-[14px] font-[600] text-[#414141]">Attendance</p>
</div>
</div>
</div>
<div className="flex justify-center place-items-center border-r-[1px] border-[#CFCFCF] my-3">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/note.svg" alt="" />
</div>
<div className="flex flex-col">
<p className="text-[20px] font-[800]">
12 <span className="text-[14px] font-[500]">Questions</span>
</p>
<p className="text-[14px] font-[600] text-[#414141]">Attempted</p>
</div>
</div>
</div>
<div className="flex justify-center place-items-center my-3">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/note.svg" alt="" />
</div>
<div className="flex flex-col">
<p className="text-[20px] font-[800]">
12 <span className="text-[14px] font-[500]">Correct</span>
</p>
<p className="text-[14px] font-[600] text-[#414141]">Attempts</p>
</div>
</div>
</div>
</div>
{selectedQuiz.questions.map((questionData) => (
<div key={questionData.questionId} className="mb-4 px-10 flex flex-col space-y-2">
<p className="text-[20px] font-[700]">
Q{questionData.questionId}: {questionData.questionText}
</p>
<p className="text-[16px] font-[600] text-[#EF7A0C]">Your Answer</p>
<p className="text-[20px] font-[500]">{questionData.correctAnswer}</p>
<div className="inline-flex place-items-center space-x-4 w-full border-[1px] border-[#218B32] rounded-[10px] p-3">
<p className="text-[14px] font-[700] text-[#218B32] inline-flex place-items-center">
<img src="../../assets/green-tick.svg" alt="" /> &nbsp;Correct
</p>
<p className="text-[14px] font-[400]"> {questionData.correctAnswer}</p>
</div>
<ul>
{/* {questionData.options.map((option, index) => (
<li key={index}>{option}</li>
))} */}
</ul>
</div>
))}
</Modal>
)}
</section>
);
}

View File

@ -0,0 +1,251 @@
import React, { useState, useEffect } from 'react';
import { Modal } from 'antd';
interface Question {
questionId: string;
questionText: string;
correctAnswer: string;
options: string[];
}
interface Quiz {
quizId: string;
quizName: string;
internalMarks: string;
attendance: string;
attendQuestion: string;
totalQuestion: string;
questions: Question[];
}
interface Module {
moduleId: string;
type: string;
moduleName: string;
quizzes: Quiz[];
}
interface QuestionList {
questionId: string;
questionText: string;
correctAnswer: string;
options: string[];
moduleId: string;
}
interface ModuleList {
moduleId: string;
}
export default function Index() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedQuiz, setSelectedQuiz] = useState<Quiz | null>(null);
const [quizModuleData, setQuizModuleData] = useState<Module[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
const [questionList, setQuestionList] = useState<QuestionList[]>([]);
const [moduleList, setModuleList] = useState<ModuleList[]>([]);
useEffect(() => {
fetch(`http://localhost:5174/api/question-list`)
.then((res) => {
if (!res.ok) {
throw new Error('Network Response not ok');
}
return res.json();
})
.then((questionData) => {
setQuestionList(questionData);
console.log('Question List', questionData);
})
.catch((error) => {
console.error('Error fetching question list:', error);
});
}, []);
useEffect(() => {
if (questionList.length > 0) {
const fetchModuleList = async () => {
try {
const moduleData = await Promise.all(
questionList.map((question) =>
fetch(`http://localhost:5174/api/quiz-module-list`)
.then((res) => {
if (!res.ok) {
throw new Error('Network Response not ok');
}
return res.json();
})
)
);
setModuleList(moduleData.flat());
console.log('Module List', moduleData.flat());
} catch (error) {
console.error('Error fetching module list:', error);
}
};
fetchModuleList();
}
}, [questionList]);
useEffect(() => {
fetch('http://localhost:5174/api/quiz-module')
.then((res) => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then((data) => {
// console.log('Fetched data:', data);
// Extract the modules array from the response
if (data && Array.isArray(data.modules)) {
setQuizModuleData(data.modules);
} else {
setError(new Error('Fetched data is not an array'));
}
setLoading(false);
})
.catch((error) => {
console.error('Error fetching data:', error);
setError(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
const showModal = (quiz: Quiz) => {
setSelectedQuiz(quiz);
setIsModalOpen(true);
};
const handleOk = () => {
setIsModalOpen(false);
setSelectedQuiz(null);
};
const handleCancel = () => {
setIsModalOpen(false);
setSelectedQuiz(null);
};
return (
<section className="">
<div className="flex flex-col">
{quizModuleData.length > 0 ? (
quizModuleData.map((moduleData) => (
<div key={moduleData.moduleId}>
<div className="p-6">
<p className="text-[16px] font-[700] text-[#EF7A0C]">{moduleData.type}</p>
<p className="text-[22px] font-[700]">{moduleData.moduleName}</p>
<p className="text-[14px] font-[600]">3/8 Quizzes Completed </p>
</div>
<div className="flex flex-col">
{moduleData.quizzes.map((quizData) => (
<div onClick={() => showModal(quizData)} className="flex flex-row justify-between place-items-center hover:bg-[#FFF4EA] duration-500 border-b-[1px] border-b-[#CFCFCF] p-6 cursor-pointer" key={quizData.quizId}>
<div className="flex flex-col space-y-2">
<h3 className="text-[20px] font-[700]">
#{quizData.quizId} {quizData.quizName}
</h3>
<p className="text-[16px] font-[700] text-[#6E6E6E]">
<span>Internal Marks: {quizData.internalMarks}</span>
&nbsp;&#8226; &nbsp;
<span>Attendance: {quizData.attendance}</span>
</p>
</div>
<div className="flex flex-row space-x-4">
<p className="bg-[#FFE2C7] p-2 rounded-[8px]">
<span className="text-[32px] font-[700] text-[#EF7A0C]">{quizData.attendQuestion}</span>/
<span className="text-[16px] font-[700] ">{quizData.totalQuestion}</span>
</p>
<img src="/assets/right-arrow.svg" alt="" />
</div>
</div>
))}
</div>
</div>
))
) : (
<div>No quiz modules available.</div>
)}
</div>
{selectedQuiz && (
<Modal title={selectedQuiz.quizName} open={isModalOpen} onOk={handleOk} onCancel={handleCancel} width={1000}>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 border-b-[1px] border-b-[#CFCFCF]">
<div className="flex justify-center place-items-center border-r-[1px] border-[#CFCFCF] my-3">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/calendar.svg" alt="" />
</div>
<div className="flex flex-col">
<p className="text-[20px] font-[800]">18/10</p>
<p className="text-[14px] font-[600] text-[#414141]">Attendance</p>
</div>
</div>
</div>
<div className="flex justify-center place-items-center border-r-[1px] border-[#CFCFCF] my-3">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/note.svg" alt="" />
</div>
<div className="flex flex-col">
<p className="text-[20px] font-[800]">
12 <span className="text-[14px] font-[500]">Questions</span>
</p>
<p className="text-[14px] font-[600] text-[#414141]">Attempted</p>
</div>
</div>
</div>
<div className="flex justify-center place-items-center my-3">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/note.svg" alt="" />
</div>
<div className="flex flex-col">
<p className="text-[20px] font-[800]">
12 <span className="text-[14px] font-[500]">Correct</span>
</p>
<p className="text-[14px] font-[600] text-[#414141]">Attempts</p>
</div>
</div>
</div>
</div>
{questionList.map((questionData) => (
<div key={questionData.questionId} className="mb-4 px-10 flex flex-col space-y-2">
<p className="text-[20px] font-[700]">
Q{questionData.questionId}: {questionData.questionText}
</p>
<p className="text-[16px] font-[600] text-[#EF7A0C]">Your Answer</p>
<p className="text-[20px] font-[500]">{questionData.correctAnswer}</p>
<div className="inline-flex place-items-center space-x-4 w-full border-[1px] border-[#218B32] rounded-[10px] p-3">
<p className="text-[14px] font-[700] text-[#218B32] inline-flex place-items-center">
<img src="../../assets/green-tick.svg" alt="" /> &nbsp;Correct
</p>
<p className="text-[14px] font-[400]"> {questionData.correctAnswer}</p>
</div>
<ul>
{/* {questionData.options.map((option, index) => (
<li key={index}>{option}</li>
))} */}
</ul>
</div>
))}
</Modal>
)}
</section>
);
}

View File

@ -0,0 +1,44 @@
export default function Index() {
return(
<section className="container mx-auto">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 ">
<div className="flex flex-col justify-center place-items-center border-r-[1px] border-[#CFCFCF] my-6">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/calendar.svg" alt="" />
</div>
<p className="text-[32px] font-[800]">70%</p>
</div>
<p className="text-[16px] font-[600] text-[#414141] py-2">Average Attendance</p>
</div>
<div className="flex flex-col justify-center place-items-center border-r-[1px] border-[#CFCFCF] my-6">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/cart.svg" alt="" />
</div>
<p className="text-[32px] font-[800]">02</p>
</div>
<p className="text-[16px] font-[600] text-[#414141] py-2">Total Certificates</p>
</div>
<div className="flex flex-col justify-center place-items-center border-r-[1px] border-[#CFCFCF] my-6">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/note.svg" alt="" />
</div>
<p className="text-[32px] font-[800]">12</p>
</div>
<p className="text-[16px] font-[600] text-[#414141] py-2">Tests Taken</p>
</div>
<div className="flex flex-col justify-center place-items-center my-6">
<div className="flex flex-row space-x-2">
<div className="w-[53px] h-[53px] bg-[#FFF1E3] rounded-full flex justify-center place-items-center">
<img className=" " src="../../assets/module.svg" alt="" />
</div>
<p className="text-[32px] font-[800]">0</p>
</div>
<p className="text-[16px] font-[600] text-[#414141] py-2">Modules Completed</p>
</div>
</div>
</section>
)
}

View File

@ -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(`http://localhost:5174/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>
);
}

View File

@ -0,0 +1,13 @@
export default function QuizHeader(){
return(
<section className="container-fluid bg-[#000] ">
<div className="flex flex-row justify-center gap-x-8 py-6">
<p className="text-[42px] w-[42px] h-[31px]"></p>
<div className="flex flex-col justify-center place-items-center">
<p className="text-[#FFF] text-[24px] font-[700]"> Take an AI Generative Quiz</p>
<p className="text-[#FFF] text-[16px] font-[400]">Convert any text into an interactive quiz session</p>
</div>
</div>
</section>
)
}

View File

@ -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(`http://localhost:5174/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>
);
}

View File

@ -0,0 +1,65 @@
import { Flex, Progress } from 'antd';
import React, { useEffect, useState } from 'react';
interface Performer {
quizId: number;
quizType: string;
quizName: string;
percentage: string;
}
export default function quizScoreData() {
const [quizData, setData] = useState<Performer[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch('http://localhost:5174/api/quiz-score')
.then(res => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setError(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return(
<section>
<div className="border-[1px] border-[#CFCFCF] rounded-t-[10px]" style={{background: 'linear-gradient(138.22deg, #4377C6 0%, #092E76 180.99%)'}}>
<h2 className="text-[20px] font-[700] text-[#FFF] p-4">Quizzes score</h2>
<div className="flex flex-col">
{quizData.slice(0, 10).map((data => (
<a key={data.quizId} href='#' className='flex flex-row justify-between place-items-center bg-[#FCFCFC] border-b-[1px] border-b-[#CFCFCF] p-4'>
<div className='flex flex-col'>
<p className='text-[14px] font-[600] text-[#EF7A0C]'>{data.quizType}</p>
<p className='text-[16px] font-[700]'>{data.quizName}</p>
</div>
<div className='flex flex-row'>
<Progress type="dashboard" percent={Number(data.percentage)} gapDegree={0} size={40} strokeColor="#EF7A0C" format={(percent) => (<span style={{ fontWeight: 700 }}>{percent}%</span>)}/>
<img src="../../assets/right-arrow.svg" alt="" />
</div>
</a>
)))}
</div>
</div>
</section>
)
}
// quiz-details
{/* <Progress type="dashboard" percent={75} gapDegree={30} /> */}

View File

@ -1,459 +0,0 @@
import React, {useState} from 'react';
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined} from '@ant-design/icons';
import Icon from '@ant-design/icons';
import AdministrationIcon from '~/components/customIcon/AdministrationIcon';
import MyCoursesIcon from '~/components/customIcon/MyCoursesIcon';
import ExaminationIcon from '~/components/customIcon/ExaminationIcon';
import CommunityIcon from '~/components/customIcon/CommunityIcon';
import NotificationIcon from '~/components/customIcon/NotificationIcon';
import {Layout, Menu, theme, Button, Modal, MenuProps} from 'antd';
import { Dropdown, Space } from 'antd';
import '../../public/assets/student-dashboard.css';
let courseData = [
{
id : "1",
title : "Life History of Dr. Maria Montessori",
chapter : "1",
Program : "Graduate Program",
img : "../../assets/course1.jpg"
},
{
id : "2",
title : "Introduction to Montessori Methods",
chapter : "2",
Program : "Graduate Program",
img : "../../assets/course2.jpg"
},
{
id : "3",
title : "Exercises on Practical Life",
chapter : "3",
Program : "Graduate Program",
img : "../../assets/course3.jpg"
}
];
let knowledgeData = [
{
id: "1",
status: "1",
title: "Assessment on Special Education",
challenge: "Challenge yourself & climb the leaderboard.",
question: "Subjective Question",
img: "../../assets/knowledge1.jpg"
},
{
id: "2",
status: "1",
title: "Quiz on Children Psychology",
challenge: "Challenge yourself & climb the leaderboard.",
question: "MCQ",
img: "../../assets/knowledge2.jpg"
},
{
id: "3",
status: "1",
title: "Quiz on Montessori Methods",
challenge: "Challenge yourself & climb the leaderboard.",
question: "MCQ",
img: "../../assets/knowledge3.jpg"
}
];
let performersData = [
{
id: "1",
name: "Eiden",
score: "48/50",
points: "999",
rank: "1",
program: "Graduate Program",
avatar: "avatar1.png"
},
{
id: "2",
name: "Jackson",
score: "45/50",
points: "997",
rank: "2",
program: "Graduate Program",
avatar: "avatar2.png"
},
{
id: "3",
name: "Emma Aria",
score: "43/50",
points: "994",
rank: "3",
program: "Graduate Program",
avatar: "avatar3.png"
},
{
id: "4",
name: "John Doe",
score: "40/50",
points: "990",
rank: "4",
program: "Graduate Program",
avatar: "avatar4.png"
},
{
id: "5",
name: "Jane Cooper",
score: "37/50",
points: "987",
rank: "5",
program: "Graduate Program",
avatar: "avatar5.png"
},
{
id: "6",
name: "John Doe",
score: "35/50",
points: "982",
rank: "6",
program: "Graduate Program",
avatar: "avatar6.png"
}
];
const sortedData = performersData.sort((a, b) => parseInt(a.rank) - parseInt(b.rank));
const highestRank = sortedData[0];
const secondHighestRank = sortedData[1];
const thirdHighestRank = sortedData[2];
console.log('The highest rank is:', highestRank);
console.log('The second highest rank is:', secondHighestRank);
console.log('The Third highest rank is:', thirdHighestRank);
// const highestRank = performersData.reduce((prev, current) => (prev.rank < current.rank) ? prev : current);
// console.log('The highest rank is:', highestRank);
const { Header, Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items2: MenuProps['items'] = [
{
key: 'subsd1',
icon: <AdministrationIcon />,
label: (<p>&nbsp; Administration</p>),
children: [
{
key: '1sd',
label: (<a href='#'>Class Schedules</a>),
},
{
key: '2sd',
label: (<a href='#'>Classmate Directory</a>),
},
{
key: '3sd',
label: (<a href='#'>Qualifications</a>),
},
],
},
{
key: 'subsd2',
icon: <MyCoursesIcon />,
label: (<p>&nbsp; My Courses</p>),
children: [
{
key: '4sd',
label: (<a href='#'>Graduate Program</a>),
},
{
key: '5sd',
label: (<a href='#'>Post-Graduate Program</a>),
},
],
},
{
key: 'subsd3',
icon: <ExaminationIcon />,
label: (<p>&nbsp; Examinations</p>),
children: [
{
key: '6sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '7sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '8sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: 'subsd4',
icon: <CommunityIcon />,
label: (<p>&nbsp; Community</p>),
children: [
{
key: '9sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '10sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '11sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: 'subsd5',
icon: <NotificationIcon />,
label: (<p>&nbsp; Notifications</p>),
children: [
{
key: '12sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '13sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '14sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
// getItem('Files', '9', <FileOutlined />),
{
key: 'grp',
label: '',
type: 'group',
style: { marginTop: '100px' },
children: [
{
key: '15sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(SettingOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Settings</h2>)
},
{
key: '16sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(QuestionCircleOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Help & Support</h2>)
},
{
key: '17sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(LogoutOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Logout</h2>)
},
],
},
];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<>
{/* <Button type="primary" onClick={showLoading}>Open Modal</Button> */}
<Modal style={{top: '20px', right: '0px'}} title={<p>Loading Modal</p>} footer={ <Button type="primary" onClick={showLoading}> Reload </Button>} loading={loading} open={open} onCancel={() => setOpen(false)} >
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</>
{/* <Header style={{ display: 'flex', alignItems: 'center' }}>
<div className="demo-logo" />
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']} items={items1} style={{ flex: 1, minWidth: 0 }} />
</Header> */}
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<Menu className='custom-menu' mode="inline" style={{ height: '100%', borderRight: 0, paddingTop: 30, background: 'transparent'}} items={items2} />
</Sider>
</div>
{/* defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']} */}
<Layout style={{marginLeft: 366, background: '#FFF'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<img src="../../assets/student-dash.svg" alt=""/>
<p className='pl-1 text-[18px] font-[700] whitespace-nowrap'>Student Dashboard</p>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<svg viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.06445 20.2658V18.2111H7.1191V11.0198C7.1191 9.59872 7.54715 8.33597 8.40325 7.2316C9.25935 6.12723 10.3723 5.40382 11.742 5.06138V4.34225C11.742 3.9142 11.8919 3.55036 12.1915 3.25072C12.4911 2.95109 12.855 2.80127 13.283 2.80127C13.7111 2.80127 14.0749 2.95109 14.3746 3.25072C14.6742 3.55036 14.824 3.9142 14.824 4.34225V5.06138C16.1938 5.40382 17.3067 6.12723 18.1628 7.2316C19.0189 8.33597 19.447 9.59872 19.447 11.0198V18.2111H21.5016V20.2658H5.06445ZM13.283 23.3477C12.718 23.3477 12.2343 23.1465 11.8319 22.7442C11.4296 22.3418 11.2284 21.8581 11.2284 21.2931H15.3377C15.3377 21.8581 15.1365 22.3418 14.7341 22.7442C14.3318 23.1465 13.8481 23.3477 13.283 23.3477ZM9.17374 18.2111H17.3923V11.0198C17.3923 9.88979 16.99 8.9224 16.1852 8.11766C15.3805 7.31293 14.4131 6.91056 13.283 6.91056C12.153 6.91056 11.1856 7.31293 10.3808 8.11766C9.57611 8.9224 9.17374 9.88979 9.17374 11.0198V18.2111Z" fill="black"/>
<circle cx="19.4462" cy="19.2384" r="4.23771" fill="#FF0000" stroke="#fff" strokeWidth="2.31148"/>
</svg>
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
<section className='border-b-[1px] border-[#CFCFCF]'>
<div className='container mx-auto'>
<h2 className='text-[20px] font-[700] my-4 py-2 inline-flex leading-[24px]'>Graduate Program</h2>
</div>
</section>
<section className='bg-[#FCFCFC]'>
<div className='container mx-auto'>
<h2 className='text-[20px] font-[700] my-4 inline-flex leading-[24px]'>Continue Learning <img src="../../assets/right-arrow.svg" alt="" /></h2>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'>
{courseData.map(data=>(
<div key={data.id} className=''>
<img className='w-full rounded-[10px]' src={data.img} alt="" />
<h2 className='text-[16px] font-[700] my-2'>{data.title}</h2>
<p className='text-[14px] font-[500] text-[#6E6E6E]'>
<span>Chapter {data.chapter}</span> &#8226; &nbsp;
<span>{data.Program}</span>
</p>
</div>
))}
</div>
</div>
</section>
{/* knowledgeData */}
<section className='container mx-auto my-16'>
<div className='grid grid-cols-1 xl:grid-cols-7 gap-y-6 border-[1px] border-[#CFCFCF]'>
<div className='xl:col-span-5 border-r-[1px] border-[#CFCFCF]'>
<h2 className='text-[20px] font-[700] inline-flex p-6'>Knowledge Quests <img src="../../assets/right-arrow.svg" alt="" /></h2>
<div className='flex flex-col gap-6'>
{knowledgeData.map(data => (
<div key={data.id} className='flex flex-row justify-between px-6 place-items-center'>
<div className='flex flex-row justify-between gap-6'>
<img src={data.img} alt="" />
<div className='flex flex-col space-y-3'>
<h2 className='text-[16px] font-[700] text-[#000]'>{data.title}</h2>
<p className='text-[14px] font-[600] text-[#525252]'>{data.challenge}</p>
<p className='text-[14px] font-[600] text-[#9D9D9D]'>{data.question}</p>
</div>
</div>
<button className='bg-[#000] text-[#FFF] rounded-[8px] px-16 py-3 h-fit text-[18px] font-[600]'>Start</button>
</div>
))}
</div>
</div>
<div className='xl:col-span-2'>
<h2 className='text-[20px] font-[700] inline-flex px-4 pt-4'>Top Performers <img src="../../assets/right-arrow.svg" alt="" /></h2>
<p className='text-[16px] font-[700] text-[#6E6E6E] px-4 pb-4 mb-28'>Knowledge Quest</p>
<div className='flex flex-row justify-between place-items-center space-x-2 border-b-[1px] border-[#CFCFCF]'>
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='mx-auto h-[52px] w-[60px] ' src={`../../assets/${secondHighestRank.avatar}`} alt="" />
<img className='absolute mt-12' src="../../assets/bacth2.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{secondHighestRank.name}</p>
<p className='text-[12px] font-[700] text-center'>{secondHighestRank.score}</p>
</div>
<div className='w-full mx-auto h-[130px] -mt-[42px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='-mt-10' src="../../assets/crown.png" alt="" />
<img className='mx-auto h-[52px] w-[60px]' src={`../../assets/${highestRank.avatar}`} alt="" />
<img className='absolute mt-12' src="../../assets/bacth1.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{highestRank.name}</p>
<p className='text-[12px] font-[700] text-center'>{highestRank.score}</p>
</div>
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='mx-auto h-[52px] w-[60px]' src={`../../assets/${thirdHighestRank.avatar}`} alt="" />
<img className='absolute mt-12' src="../../assets/bacth3.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{thirdHighestRank.name}</p>
<p className='text-[12px] font-[700] text-center'>{thirdHighestRank.score}</p>
</div>
</div>
<div className='flex flex-col'>
{sortedData.slice(3).map(data => (
<div key={data.id} className='flex flex-row justify-between place-items-center border-b-[1px] border-[#CFCFCF] p-2'>
<p className='text-[11px] font-[700]'># {data.rank}</p>
<img className='w-[35px] h-[35px]' src={`../../assets/${data.avatar}`} alt="" />
<div>
<p className='text-[14px] font-[700]'>{data.name}</p>
<p className='text-[10px] font-[700] text-[#6E6E6E]'>{data.program}</p>
</div>
<div className='flex flex-col justify-center place-items-center'>
<img src="../../assets/points-icon.svg" alt="" />
<p className='text-[10px] font-[700]'>{data.points} Points</p>
</div>
</div>
))}
</div>
</div>
</div>
</section>
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -0,0 +1,137 @@
type TheoryData = {
id: number;
module: number;
status: number;
time: number;
access: number;
title: string;
description: string;
img: string;
total_marks: string;
};
let theoryData: TheoryData[] = [
{
id: 1,
module: 1,
status: 2,
time: 4,
access: 1,
title: "Life History of Dr. Maria Montessori",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/image1.jpg",
total_marks: "50"
},
{
id: 2,
module: 2,
status: 1,
time: 4,
access: 1,
title: "Introduction to Montessori Methods",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/image2.jpg",
total_marks: "50"
},
{
id: 3,
module: 3,
status: 0,
time: 4,
access: 0,
title: "Exercises in Practical Life",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/image3.jpg",
total_marks: "50"
},
{
id: 1,
module: 1,
status: 0,
time: 4,
access: 0,
title: "Life History of Dr. Maria Montessori",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/image1.jpg",
total_marks: "50"
},
{
id: 2,
module: 2,
status: 0,
time: 4,
access: 0,
title: "Introduction to Montessori Methods",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/image2.jpg",
total_marks: "50"
},
{
id: 3,
module: 3,
status: 0,
time: 4,
access: 0,
title: "Exercises in Practical Life",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
img: "/assets/image3.jpg",
total_marks: "50"
}
];
export default function CourseTheory() {
const getStatusText = (status: number): string => {
if (status === 2) return "<p style='color: #218B32; font-weight: 600; font-size: 18px; display: inline-flex;'><img style='margin-right: 8px;' src='/assets/green-tick.svg' />Finished</p>";
if (status === 1) return "<p style='color: #EF7A0C; font-weight: 600; font-size: 18px' >40% Completed</p>";
if (status === 0) return " ";
return "";
}
return(
<div>
<section className="container mx-auto p-4 px-10">
<div className="flex flex-row justify-between place-items-center rounded-[10px]" style={{background: 'linear-gradient(90.65deg, #4377C6 0%, #3B70C0 100%)'}}>
<div className="flex flex-row h-[107px] place-items-center p-4 space-x-6">
<div className="relative inline-block">
<img className="h-[81px] w-[137px] rounded-[10px]" src="/assets/image3.jpg" alt="" />
<button className="absolute inset-0 m-auto h-10 w-10">
<img src="/assets/play.svg" alt="" />
</button>
</div>
<div className="">
<h2 className="tet-[18px] font-[700] text-[#FFF] w-[328px]">Lorem ipsum dolor sit amet, consectetur adipiscing elit</h2>
<p className="text-[14px] font-[600] text-[#EF7A0C]">
<span> Video</span> &nbsp;|&nbsp;
<span> 30 mins</span>
</p>
</div>
</div>
<div className="pr-4">
<button className="bg-[#FFF] text-[#000] font-[600] px-6 py-2 text-[18px] rounded-[8px]">Continue Learning</button>
</div>
</div>
</section>
<section className="container mx-auto px-4">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 p-6 gap-10 ">
{
theoryData.map((data, index) => (
<div key={index} className={`flex flex-col border-[1px] border-[#218B32] p-3 rounded-[10px] ${data.access === 0 ? 'contrast-[0.3]' : ''} `}>
<div className="inline-block relative">
<img className="w-full rounded-[8px] " src={data.img} alt="" />
<p className="absolute inset-0 top-4 left-4 w-fit h-fit text-[12px] font-[600] text-[#FFF] bg-[#218B32] rounded-[8px] px-[20px] py-[10px]">MODULE {data.module}</p>
</div>
<h2 className="text-[18px] font-[700]">{data.title}</h2>
<p className="text-[14px] font-[700] text-[#EF7A0C] py-2"><span>{data.time} Hours</span> | <span>Net Total Marks {data.total_marks}</span></p>
<p className="text-[14px] font-[500] text-[#6E6E6E] pb-6">{data.description}</p>
<div className="flex flex-row justify-between place-items-center">
<button disabled={data.access === 0} className={`text-[18px] font-[600] bg-[#000] rounded-[8px] px-[50px] py-2 text-[#fff] ${data.access == 0 ? 'cursor-not-allowed' : ''}`}>{data.access === 0 ? 'Locked' : 'View'}</button> <div dangerouslySetInnerHTML={{ __html: getStatusText(data.status) }} />
</div>
</div>
))
}
</div>
</section>
</div>
)
}

View File

@ -0,0 +1,27 @@
import React from 'react';
import { Timeline } from 'antd';
const AntdTimeline = () => (
<Timeline>
<Timeline.Item>Event 1: Start of the project - 2024-01-01</Timeline.Item>
<Timeline.Item color='green'>
Event 2: Initial Design - 2024-02-01
<div style={{ marginTop: '10px' }}>
<video width="320" height="240" controls>
<source src="https://videos.pexels.com/video-files/3195394/3195394-sd_640_360_25fps.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>
</div>
</Timeline.Item>
<Timeline.Item>
Event 3: Development Phase - 2024-03-01
<div style={{ marginTop: '10px' }}>
<embed src="https://pdfobject.com/pdf/sample.pdf" style={{width: '100%'}} height="375" type="application/pdf" />
</div>
</Timeline.Item>
<Timeline.Item>Event 4: Testing - 2024-04-01</Timeline.Item>
<Timeline.Item>Event 5: Launch - 2024-05-01</Timeline.Item>
</Timeline>
);
export default AntdTimeline;

View File

@ -0,0 +1,102 @@
import React, { useEffect, useState } from 'react';
interface Performer {
id: number;
name: string;
rank: number;
avatar: string;
score: number;
program: string;
points: number;
}
export default function TopPerformers() {
const [data, setData] = useState<Performer[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch('http://localhost:5174/api/top-performers')
.then(res => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then(data => {
// console.log(data)
const sortedData: Performer[] = data.sort((a: Performer, b: Performer) => a.rank - b.rank);
setData(sortedData);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setError(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
const [highestRank, secondHighestRank, thirdHighestRank, ...sortedData] = data;
return (
<div className=''>
<h2 className='text-[20px] font-[700] inline-flex px-4 pt-4'>
Top Performers <img src="/assets/right-arrow.svg" alt="" />
</h2>
<p className='text-[16px] font-[700] text-[#6E6E6E] px-4 pb-4 mb-28'>Knowledge Quest</p>
<div className='flex flex-row justify-between place-items-center border-b-[1px] border-[#CFCFCF]'>
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='mx-auto h-[53px] w-[54px] rounded-full' src={secondHighestRank.avatar} alt="" />
<img className='absolute mt-12' src="/assets/bacth2.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{secondHighestRank.name}</p>
<p className='text-[12px] font-[700] text-center'>{secondHighestRank.points} Points</p>
</div>
<div className='w-full mx-auto h-[130px] -mt-[42px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='-mt-10' src="/assets/crown.png" alt="" />
<img className='mx-auto h-[53px] w-[54px] rounded-full' src={highestRank.avatar} alt="" />
<img className='absolute mt-9' src="/assets/bacth1.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{highestRank.name}</p>
<p className='text-[12px] font-[700] text-center'>{highestRank.points} Points</p>
</div>
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
<img className='mx-auto h-[53px] w-[54px] rounded-full' src={thirdHighestRank.avatar} alt="" />
<img className='absolute mt-12' src="/assets/bacth3.svg" alt="" />
</div>
<p className='text-[12px] font-[700] text-center mt-4'>{thirdHighestRank.name}</p>
<p className='text-[12px] font-[700] text-center'>{thirdHighestRank.points} Points</p>
</div>
</div>
<div className='flex flex-col'>
{sortedData.map(data => (
<div key={data.id} className='flex flex-row justify-between place-items-center border-b-[1px] border-[#CFCFCF] p-2'>
<p className='text-[11px] font-[700]'># {data.rank}</p>
<img className='w-[35px] h-[35px]' src={data.avatar} alt="" />
<div>
<p className='text-[14px] font-[700]'>{data.name}</p>
<p className='text-[10px] font-[700] text-[#6E6E6E]'>{data.program}</p>
</div>
<div className='flex flex-col justify-center place-items-center'>
<img src="/assets/points-icon.svg" alt="" />
<p className='text-[10px] font-[700]'>{data.points} Points</p>
</div>
</div>
))}
</div>
</div>
);
}

View File

@ -0,0 +1,11 @@
export default function(){
return(
<div className="">
<h2 className="text-[20px] font-[700] my-6">Your Certificates</h2>
<div className="border-[1px] border-[#E9E9E9] rounded-[12px] bg-[#FCFCFC] p-4">
<div className="h-[260px] bg-[#FFF1E3] rounded-[10px]"></div>
</div>
</div>
)
}

View File

@ -1,10 +1,12 @@
import type { MetaFunction } from "@remix-run/node";
import TestComponent from '../components/TestComponent'; // Fix typo here
import TestComponent from '../components/StudentDashboard-no-content'; // Fix typo here
import TimeLine from '~/components/Timeline';
export default function Index() {
return (
<div>
<TestComponent />
<TimeLine />
{/* <TestComponent /> */}
</div>
);
}

View File

@ -0,0 +1,9 @@
import AdminNav from '~/components/AdminNav'
export default function AdminIndex(){
return(
<div>
<AdminNav />
</div>
)
}

View File

View File

@ -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>
);
}

View File

@ -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>
);
}

View File

@ -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>
);
}

View File

@ -36,7 +36,7 @@ function toggleSection() {
export default function Index() {
const [percent, setPercent] = useState(0);
const [secondsLeft, setSecondsLeft] = useState(5);
const [secondsLeft, setSecondsLeft] = useState(10);
useEffect(() => {
const interval = setInterval(() => {
@ -45,7 +45,7 @@ export default function Index() {
clearInterval(interval);
return 100;
}
return Math.round(prevPercent + (100 / 5)); // Round percentage
return Math.round(prevPercent + (100 / 10)); // Round percentage
});
setSecondsLeft((prevSeconds) => {
if (prevSeconds <= 1) {
@ -76,13 +76,13 @@ export default function Index() {
<label className="text-[18px] font-[500] my-4" htmlFor="textToUse">Text to Use</label>
<p className="text-[16px] font-[500] text-[#9D9D9D]"><span id="letterLength"></span><span>/2000</span></p>
</div>
<textarea onChange={letterCount} name="queryMessage" id="queryMessage" rows="6" maxLength="200" className="focus:outline-none border-[1px] border-[#CFCFCF] rounded-[8px] p-6" placeholder="Enter the topic youd like to generate a quiz for."></textarea>
<textarea onChange={letterCount} name="queryMessage" id="queryMessage" rows={6} maxLength={2000} className="focus:outline-none border-[1px] border-[#CFCFCF] rounded-[8px] p-6" placeholder="Enter the topic youd like to generate a quiz for."></textarea>
</div>
<h2 className="text-[18px] font-[500] my-4">Trending</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div className="border-[1px] border-[#CFCFCF] rounded-[8px]">
<div className="bg-[#C5DCFF] rounded-t-[8px] flex justify-center place-items-center">
<img className="p-6" src="../../assets/quiz-logo.svg" alt="" />
<img className="p-6" src="/assets/quiz-logo.svg" alt="" />
</div>
<div className="flex flex-col justify-center px-3 py-2">
<h3 className="text-[14px] font-[500] ">Dr. Marie Montessori Life Journey</h3>
@ -91,7 +91,7 @@ export default function Index() {
</div>
<div className="border-[1px] border-[#CFCFCF] rounded-[8px]">
<div className="bg-[#E2C5FF] rounded-t-[8px] flex justify-center place-items-center">
<img className="p-6" src="../../assets/quiz-logo.svg" alt="" />
<img className="p-6" src="/assets/quiz-logo.svg" alt="" />
</div>
<div className="flex flex-col justify-center px-3 py-2">
<h3 className="text-[14px] font-[500]">Montessori Methods</h3>
@ -100,7 +100,7 @@ export default function Index() {
</div>
<div className="border-[1px] border-[#CFCFCF] rounded-[8px]">
<div className="bg-[#FFD0C5] rounded-t-[8px] flex justify-center place-items-center">
<img className="p-6" src="../../assets/quiz-logo.svg" alt="" />
<img className="p-6" src="/assets/quiz-logo.svg" alt="" />
</div>
<div className="flex flex-col justify-center px-3 py-2">
<h3 className="text-[14px] font-[500] ">Practical Methods</h3>
@ -112,17 +112,17 @@ export default function Index() {
<div className="flex flex-col md:flex-row gap-[10px]">
<div className="drop-shadow-2xl">
<button className="inline-flex justify-center place-items-center border-[1px] border-[#CFCFCF] rounded-[8px] px-[20px] py-[12px] text-[16px] font-[500] text-[#525252]">
<img src="../../assets/button-icon.svg" alt="" /> &nbsp; Simplify Questions
<img src="/assets/button-icon.svg" alt="" /> &nbsp; Simplify Questions
</button>
</div>
<div className="drop-shadow-2xl">
<button className="inline-flex justify-center place-items-center border-[1px] border-[#CFCFCF] rounded-[8px] px-[20px] py-[12px] text-[16px] font-[500] text-[#525252]">
<img src="../../assets/button-icon.svg" alt="" /> &nbsp; Similar Topics
<img src="/assets/button-icon.svg" alt="" /> &nbsp; Similar Topics
</button>
</div>
<div className="drop-shadow-2xl">
<button className="inline-flex justify-center place-items-center border-[1px] border-[#CFCFCF] rounded-[8px] px-[20px] py-[12px] text-[16px] font-[500] text-[#525252]">
<img src="../../assets/button-icon.svg" alt="" /> &nbsp; Make it fun & easy
<img src="/assets/button-icon.svg" alt="" /> &nbsp; Make it fun & easy
</button>
</div>
</div>
@ -138,9 +138,9 @@ export default function Index() {
<button onClick={toggleSection} className="px-[40px] py-[12px] text-[18px] font-[600] text-[#FFF] rounded-[10px] bg-[#000]">Generate Quiz</button>
</div>
</section>
<section id="loadingSection" style={{display: 'none'}} className="container mx-auto max-w-[894px] shadow-xl rounded-xl px-10 py-8 my-8">
<section id="loadingSection" style={{display: 'none'}} className="container mx-auto max-w-[894px] shadow-xl rounded-xl px-10 py-8 my-8 mt-[200px]">
<div className="flex flex-col justify-center place-items-center my-auto ">
<img src="../../assets/robot.png" alt="" />
<img src="/assets/robot.png" alt="" />
<h2 className="text-[24px] font-[500] py-3">Generating Quiz</h2>
<p className="text-[14px] font-[400] text-[#525252]">This usually takes <span>{secondsLeft}</span> seconds</p>
<div className='w-full sm:w-1/2'>

View File

@ -0,0 +1,107 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import AlbumArtCraft from '~/components/AlbumArt&Craft';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/mycourse">Course</a>,},{title: <a href="/mycourse/albums">Albums</a>,},{title: 'Art & Craft Album'}]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<AlbumArtCraft />
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -0,0 +1,107 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import AlbumsGKGroupActivity from '~/components/AlbumsGK&GroupActivity';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/mycourse">Course</a>,},{title: <a href="/mycourse/albums">Albums</a>,}, {title: 'GK & Group Activity'}]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<AlbumsGKGroupActivity />
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -0,0 +1,107 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import AlbumsLanguageMaths from '~/components/AlbumsLanguage&Maths';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/mycourse">Course</a>,},{title: <a href="/mycourse/albums">Albums</a>,}, {title: 'Language & Maths'}]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<AlbumsLanguageMaths />
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -0,0 +1,108 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import ClassShedules from '~/components/ClassShedules';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div>
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/administration">Administration</a>,}, {title: 'Class Schedule'}]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<ClassShedules />
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -1,311 +1,54 @@
import React, {useState} from 'react';
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined} from '@ant-design/icons';
import Icon from '@ant-design/icons';
import AdministrationIcon from '~/components/customIcon/AdministrationIcon';
import MyCoursesIcon from '~/components/customIcon/MyCoursesIcon';
import ExaminationIcon from '~/components/customIcon/ExaminationIcon';
import CommunityIcon from '~/components/customIcon/CommunityIcon';
import NotificationIcon from '~/components/customIcon/NotificationIcon';
import ClassMates from '~/components/ClassMates';
import TopPerformers from '~/components/TopPerformers';
import ClassmateTutorSection from '~/components/ClassmateTutorSection';
import {Layout, Menu, theme, Button, Modal, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/student-dashboard.css';
let classmatesData = [
{
id: "1",
name: "Daniel Nguyen",
program: "Graduate Program",
type: "Student",
avatar: "avatar1.png"
},
{
id: "2",
name: "Sarah Anderson",
program: "Post-Graduate Program",
type: "Student",
avatar: "avatar2.png"
},
{
id: "3",
name: "John Smith",
program: "Undergraduate Program",
type: "Student",
avatar: "avatar3.png"
},
{
id: "4",
name: "Emily Davis",
program: "Graduate Program",
type: "Student",
avatar: "avatar4.png"
},
{
id: "5",
name: "Michael Johnson",
program: "Post-Graduate Program",
type: "Student",
avatar: "avatar5.png"
},
{
id: "6",
name: "Jessica Wilson",
program: "Undergraduate Program",
type: "Student",
avatar: "avatar6.png"
},
{
id: "7",
name: "David Brown",
program: "Graduate Program",
type: "Student",
avatar: "avatar1.png"
},
{
id: "8",
name: "Laura Lee",
program: "Post-Graduate Program",
type: "Student",
avatar: "avatar2.png"
},
{
id: "9",
name: "Chris Miller",
program: "Undergraduate Program",
type: "Student",
avatar: "avatar3.png"
},
{
id: "10",
name: "Sophia Taylor",
program: "Graduate Program",
type: "Student",
avatar: "avatar4.png"
},
{
id: "11",
name: "James Anderson",
program: "Post-Graduate Program",
type: "Student",
avatar: "avatar5.png"
},
{
id: "12",
name: "Olivia Thomas",
program: "Undergraduate Program",
type: "Student",
avatar: "avatar6.png"
},
{
id: "13",
name: "Ethan Martinez",
program: "Graduate Program",
type: "Student",
avatar: "avatar1.png"
},
{
id: "14",
name: "Ava Garcia",
program: "Post-Graduate Program",
type: "Student",
avatar: "avatar2.png"
},
{
id: "15",
name: "Noah Rodriguez",
program: "Undergraduate Program",
type: "Student",
avatar: "avatar3.png"
},
{
id: "16",
name: "Mia Martinez",
program: "Graduate Program",
type: "Student",
avatar: "avatar4.png"
},
{
id: "17",
name: "Lucas Wilson",
program: "Post-Graduate Program",
type: "Student",
avatar: "avatar5.png"
},
{
id: "18",
name: "Isabella Clark",
program: "Undergraduate Program",
type: "Student",
avatar: "avatar6.png"
},
{
id: "19",
name: "Liam Walker",
program: "Graduate Program",
type: "Student",
avatar: "avatar1.png"
},
{
id: "20",
name: "Charlotte Lewis",
program: "Post-Graduate Program",
type: "Student",
avatar: "avatar2.png"
}
];
const { Header, Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const items2: MenuProps['items'] = [
{
key: 'subsd1',
icon: <AdministrationIcon />,
label: 'Administration',
children: [
{
key: '1sd',
label: (<a href='#'>Class Schedules</a>),
},
{
key: '2sd',
label: (<a href='#'>Classmate Directory</a>),
},
{
key: '3sd',
label: (<a href='#'>Qualifications</a>),
},
],
},
{
key: 'subsd2',
icon: <MyCoursesIcon />,
label: 'My Courses',
children: [
{
key: '4sd',
label: (<a href='#'>Graduate Program</a>),
},
{
key: '5sd',
label: (<a href='#'>Post-Graduate Program</a>),
},
],
},
{
key: 'subsd3',
icon: <ExaminationIcon />,
label: 'Examinations',
children: [
{
key: '6sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '7sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '8sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: 'subsd4',
icon: <CommunityIcon />,
label: 'Community',
children: [
{
key: '9sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '10sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '11sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: 'subsd5',
icon: <NotificationIcon />,
label: 'Notifications',
children: [
{
key: '12sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '13sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '14sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
// getItem('Files', '9', <FileOutlined />),
{
key: 'grp',
label: '',
type: 'group',
style: { marginTop: '100px' },
children: [
{
key: '15sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(SettingOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Settings</h2>)
},
{
key: '16sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(QuestionCircleOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Help & Support</h2>)
},
{
key: '17sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(LogoutOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Logout</h2>)
},
],
},
];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
@ -318,20 +61,7 @@ const App: React.FC = () => {
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<>
{/* <Button type="primary" onClick={showLoading}>Open Modal</Button> */}
<Modal style={{top: '20px', right: '0px'}} title={<p>Loading Modal</p>} footer={ <Button type="primary" onClick={showLoading}> Reload </Button>} loading={loading} open={open} onCancel={() => setOpen(false)} >
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</>
{/* <Header style={{ display: 'flex', alignItems: 'center' }}>
<div className="demo-logo" />
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']} items={items1} style={{ flex: 1, minWidth: 0 }} />
</Header> */}
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
@ -340,64 +70,62 @@ const App: React.FC = () => {
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<Menu className='custom-menu' mode="inline" style={{ height: '100%', borderRight: 0, paddingTop: 30, background: 'transparent'}} items={items2} />
<LeftSideMenu />
</Sider>
</div>
{/* defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']} */}
<Layout style={{marginLeft: 366, background: '#FFF'}}>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='py-2'>
<div className='container mx-auto flex flex-row justify-between pr-10'>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" items={[{title: <a href="">Administration</a>,},{title: 'Class Directory',},]}/>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="">Administration</a>,},{title: 'Class Directory',},]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<svg viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.06445 20.2658V18.2111H7.1191V11.0198C7.1191 9.59872 7.54715 8.33597 8.40325 7.2316C9.25935 6.12723 10.3723 5.40382 11.742 5.06138V4.34225C11.742 3.9142 11.8919 3.55036 12.1915 3.25072C12.4911 2.95109 12.855 2.80127 13.283 2.80127C13.7111 2.80127 14.0749 2.95109 14.3746 3.25072C14.6742 3.55036 14.824 3.9142 14.824 4.34225V5.06138C16.1938 5.40382 17.3067 6.12723 18.1628 7.2316C19.0189 8.33597 19.447 9.59872 19.447 11.0198V18.2111H21.5016V20.2658H5.06445ZM13.283 23.3477C12.718 23.3477 12.2343 23.1465 11.8319 22.7442C11.4296 22.3418 11.2284 21.8581 11.2284 21.2931H15.3377C15.3377 21.8581 15.1365 22.3418 14.7341 22.7442C14.3318 23.1465 13.8481 23.3477 13.283 23.3477ZM9.17374 18.2111H17.3923V11.0198C17.3923 9.88979 16.99 8.9224 16.1852 8.11766C15.3805 7.31293 14.4131 6.91056 13.283 6.91056C12.153 6.91056 11.1856 7.31293 10.3808 8.11766C9.57611 8.9224 9.17374 9.88979 9.17374 11.0198V18.2111Z" fill="black"/>
<circle cx="19.4462" cy="19.2384" r="4.23771" fill="#FF0000" stroke="#fff" strokeWidth="2.31148"/>
</svg>
<img src="../../assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
</Space>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
<section className='container mx-auto '>
<div className='grid gridcols-1 md:grid-cols-7 border-[1px] border-[#CFCFCF]'>
<div className='col-span-5 border-r-[1px] border-[#CFCFCF]'>
<p className='text-[18px] font-[700] text-[#525252] border-b-[1px] border-[#CFCFCF] py-5 pl-5'><span>Your Classmates </span>| <span>Graduate Program</span></p>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>
{classmatesData.map(data => (
<div key={data.id} className='w-60 h-60 bg-cover bg-center' style={{ backgroundImage: `url('../../assets/${data.avatar}')` }}>
<img className='w-[60px] h-[60px]' src={`../../assets/${data.avatar}`} alt="" />
</div>
))}
{/* Place Content from here */}
<section className='container mx-auto'>
<div className='grid grid-cols-1 xl:grid-cols-7'>
<div className='xl:col-span-5 border-r-[1px] border-r-[#CFCFCF]'>
<ClassMates />
</div>
<div className='xl:col-span-2 p-4'>
<div>
<ClassmateTutorSection />
</div>
<div className='border-[1px] border-r-[#CFCFCF] mt-6'>
<TopPerformers />
</div>
</div>
<div className='col-span-2'>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur dignissimos nostrum fugit animi nobis. Explicabo nam accusamus harum doloremque praesentium officia, vel laborum nobis eveniet quibusdam ex rem asperiores alias!</div>
</div>
</section>
</section>
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;
export default App;

View File

View File

@ -0,0 +1,107 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import ExaminationsPractical from '~/components/ExaminationsPractical';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/examinations">Examinations</a>,},{title: 'Practical',}]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<ExaminationsPractical />
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -1,10 +1,127 @@
import type { MetaFunction } from "@remix-run/node";
import KnowledgeQuest from '../components/KnowledgeQuest'
import React, {useState} from 'react';
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined} from '@ant-design/icons';
import AdministrationIcon from '~/components/customIcon/AdministrationIcon';
import MyCoursesIcon from '~/components/customIcon/MyCoursesIcon';
import ExaminationIcon from '~/components/customIcon/ExaminationIcon';
import CommunityIcon from '~/components/customIcon/CommunityIcon';
import NotificationIcon from '~/components/customIcon/NotificationIcon';
import KnowledgeQuestsPageContent from '~/components/KnowledgeQuestsPageContent';
import TopPerformers from '~/components/TopPerformers';
import {Layout, Menu, theme, Button, Modal, MenuProps} from 'antd';
import { Dropdown, Space } from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
export default function Index() {
return (
<div>
<KnowledgeQuest /> {/* Ensure the component name matches the import */}
</div>
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: 366, background: '#FFF'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<img src="/assets/student-dash.svg" alt=""/>
<p className='pl-1 text-[18px] font-[700] whitespace-nowrap'>Student Dashboard</p>
</div>
<div className='flex flex-row place-items-center'>
<button className='bg-[#000] py-2.5 px-3 rounded-[8px] text-[#FFF] tetx-[16px] font-[600] inline-flex justify-center place-items-center'>
<img src="/assets/ai-button-icon.svg" alt="" /> AI Generative Quiz
</button>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<section className='container mx-auto my-16'>
<div className='grid grid-cols-1 xl:grid-cols-7 gap-y-6 border-[1px] border-[#CFCFCF]'>
<div className='xl:col-span-5 border-r-[1px] border-[#CFCFCF]'>
<KnowledgeQuestsPageContent />
</div>
<div className='xl:col-span-2'>
<TopPerformers />
</div>
</div>
</section>
</Content>
</Layout>
</Layout>
</Layout>
);
}
};
export default App;

View File

View File

@ -0,0 +1,109 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import AlbumsIndex from '~/components/AlbumsIndex';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/mycourse">Course</a>,},{title: 'Albums',},]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<AlbumsIndex />
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -0,0 +1,112 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import PracticalCourse from '~/components/PracticalCourses';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/mycourse">Course</a>,},{title: 'Practical',},]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="../../assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
<div className=''>
<PracticalCourse />
</div>
{/* Place Content from here */}
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -0,0 +1,112 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import TheoroCourse from '~/components/TheoryCourses';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="">Course</a>,},{title: 'Theory',},]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="../../assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
<div className=''>
<TheoroCourse />
</div>
{/* Place Content from here */}
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

View File

@ -0,0 +1,113 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import TheoryCourse from '~/components/MyCoursePracticalModule';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const Course: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/mycourse">Course</a>,},{title: <a href="/mycourse/practical">Practical</a>,},{title: 'Practical 1 : Exercises of Practical Life'}]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="../../assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
<div className=''>
<TheoryCourse />
</div>
{/* Place Content from here */}
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default Course;

View File

@ -0,0 +1,134 @@
import React, {useState} from 'react';
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined} from '@ant-design/icons';
import AdministrationIcon from '~/components/customIcon/AdministrationIcon';
import MyCoursesIcon from '~/components/customIcon/MyCoursesIcon';
import ExaminationIcon from '~/components/customIcon/ExaminationIcon';
import CommunityIcon from '~/components/customIcon/CommunityIcon';
import NotificationIcon from '~/components/customIcon/NotificationIcon';
import {Layout, Menu, theme, Button, Modal, MenuProps} from 'antd';
import ProgressReviewTopSection from '~/components/ProgressReviewTopSection';
import ProgressReview from '~/components/ProgressReview';
import QuizzesScore from '~/components/QuizzesScore'
import YourCertificates from '~/components/YourCertificates'
import { Dropdown, Space } from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: 366, background: '#FFF'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<img src="../../assets/student-dash.svg" alt=""/>
<p className='pl-1 text-[18px] font-[700] whitespace-nowrap'>Student Dashboard</p>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="../../assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
<div>
<ProgressReviewTopSection />
</div>
<div className='grid grid-cols-1 xl:grid-cols-7 border-t-[1px] border-t-[#CFCFCF]'>
<div className='xl:col-span-5 border-r-[1px] border-r-[#CFCFCF]'>
<ProgressReview />
</div>
<div className="xl:col-span-2 p-4">
<QuizzesScore />
<YourCertificates />
</div>
</div>
<div>
</div>
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

163
app/routes/quiz._index.tsx Normal file
View File

@ -0,0 +1,163 @@
import React, { useState, useEffect } from "react";
import '../../public/assets/custom-radio.css'
import QuizHeader from '~/components/QuizHeader'
interface Questiondata {
questionId: number;
questionText: string;
option1: string;
option2: string;
option3: string;
option4: string;
correctAnswer: string;
quizId: string | null;
moduleId: string;
}
interface Answerdata {
questionId: number;
selectedOption: number;
}
export default function QuizIndex() {
const [questionData, setQuestionsData] = useState<Questiondata[]>([]);
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const [selectedOption, setSelectedOption] = useState<number | null>(null);
const [answers, setAnswers] = useState<Answerdata[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
const [timeLeft, setTimeLeft] = useState(120); // 120 seconds timer
const [newQuizIds, setNewQuizIds] = useState();
useEffect(() => {
fetch(`http://localhost:5174/api/question-list`)
.then(res => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then(data => {
console.log('Question Data', data);
setQuestionsData(data);
setNewQuizIds(data[0].newQuizId)
setLoading(false);
})
.catch(error => {
console.error('An error occurred', error);
setError(error);
setLoading(false);
});
}, []);
useEffect(() => {
if (timeLeft > 0) {
const timerId = setInterval(() => setTimeLeft(timeLeft - 1), 1000);
return () => clearInterval(timerId);
} else {
handleSubmit();
}
}, [timeLeft]);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
const handleOptionChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSelectedOption(parseInt(event.target.value));
};
const handleNextQuestion = () => {
if (selectedOption !== null) {
const newAnswer = {
questionId: questionData[currentQuestionIndex].questionId,
selectedOption: selectedOption,
quizId: newQuizIds
};
setAnswers([...answers, newAnswer]);
setSelectedOption(null);
setCurrentQuestionIndex((prevIndex) => (prevIndex + 1) % questionData.length);
console.log([...answers, newAnswer]);
} else {
alert("Please select an option before proceeding to the next question.");
}
};
const handleSubmit = () => {
if (selectedOption !== null) {
const newAnswer = {
questionId: questionData[currentQuestionIndex].questionId,
selectedOption: selectedOption,
quizId: newQuizIds
};
const finalAnswers = [...answers, newAnswer];
setAnswers(finalAnswers);
console.log('Console Answers ', finalAnswers);
const apiUrl = 'http://localhost:5174/api/save-quiz-response';
fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(finalAnswers)
})
.then(response => response.json())
.then(data => {
if(data.success === true){
console.log('Find Success Message True')
window.location.href = `/quiz/result?id=${newQuizIds}`
}
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
} else {
alert("Please select an option before submitting the quiz.");
}
};
const currentQuestion = questionData[currentQuestionIndex];
return (
<div className="">
<QuizHeader />
<div className="container mx-auto max-w-[890px] mt-[100px] flex justify-end"><h2 className="text-[20px] font-[600]">Time left: {timeLeft} seconds</h2></div>
<section className="container mx-auto max-w-[890px] shadow-xl rounded-xl px-10 py-8 mb-8 border-[1px] border-[#DCDCDC] rounded-[10px] bg-[#FCFCFC] ">
<div>
<div key={currentQuestion.questionId}>
<h2 className="text-[32px] font-[700] ">{`Q${currentQuestion.questionId}. ${currentQuestion.questionText}`}</h2>
<div className="flex flex-col space-y-6 mt-8">
<label htmlFor={`${currentQuestion.questionId}-option1`} className={`flex flex-row space-x-3 border-[1px] rounded-[10px] p-3 bg-[#FFF] ${selectedOption === 1 ? 'border-[#000]' : 'border-[#D3D3D3]'}`}>
<input className="custom-radio" type="radio" value="1" id={`${currentQuestion.questionId}-option1`} checked={selectedOption === 1} onChange={handleOptionChange}/>
<span>{currentQuestion.option1}</span>
</label>
<label htmlFor={`${currentQuestion.questionId}-option2`} className={`flex flex-row space-x-3 border-[1px] rounded-[10px] p-3 bg-[#FFF] ${selectedOption === 2 ? 'border-[#000]' : 'border-[#D3D3D3]'}`}>
<input className="custom-radio" type="radio" value="2" id={`${currentQuestion.questionId}-option2`} checked={selectedOption === 2} onChange={handleOptionChange}/>
<span>{currentQuestion.option2}</span>
</label>
<label htmlFor={`${currentQuestion.questionId}-option3`} className={`flex flex-row space-x-3 border-[1px] rounded-[10px] p-3 bg-[#FFF] ${selectedOption === 3 ? 'border-[#000]' : 'border-[#D3D3D3]'}`}>
<input className="custom-radio" type="radio" value="3" id={`${currentQuestion.questionId}-option3`} checked={selectedOption === 3} onChange={handleOptionChange}/>
<span>{currentQuestion.option3}</span>
</label>
<label htmlFor={`${currentQuestion.questionId}-option4`} className={`flex flex-row space-x-3 border-[1px] rounded-[10px] p-3 bg-[#FFF] ${selectedOption === 4 ? 'border-[#000]' : 'border-[#D3D3D3]'}`}>
<input className="custom-radio" type="radio" value="4" id={`${currentQuestion.questionId}-option4`} checked={selectedOption === 4} onChange={handleOptionChange}/>
<span>{currentQuestion.option4}</span>
</label>
</div>
</div>
</div>
</section>
<div className="container mx-auto max-w-[890px] flex justify-end mt-[30px]">
{currentQuestionIndex < questionData.length - 1 ? (
<button className="bg-[#000] text-[#FFF] text-[18px] font-[600] rounded-[8px] px-[70px] py-[15px]" onClick={handleNextQuestion}>Next Question</button>
) : (
<button className="bg-[#000] text-[#FFF] text-[18px] font-[600] rounded-[8px] px-[70px] py-[15px]" onClick={handleSubmit}>Submit</button>
)}
</div>
</div>
);
}

168
app/routes/quiz.result.tsx Normal file
View File

@ -0,0 +1,168 @@
import React, { useState, useEffect } from "react";
import QuizHeader from '~/components/QuizHeader';
interface ResultData {
totalQuestions: number;
correctAnswers: number;
message: string;
}
let performersData = [
{
id: "1",
name: "Eiden",
score: "48/50",
points: "999",
rank: "1",
program: "Graduate Program",
avatar: "/assets/avatar1.png"
},
{
id: "2",
name: "Jackson",
score: "45/50",
points: "997",
rank: "2",
program: "Graduate Program",
avatar: "/assets/avatar2.png"
},
{
id: "3",
name: "Emma Aria",
score: "43/50",
points: "994",
rank: "3",
program: "Graduate Program",
avatar: "/assets/avatar3.png"
},
{
id: "4",
name: "John Doe",
score: "40/50",
points: "990",
rank: "4",
program: "Graduate Program",
avatar: "/assets/avatar4.png"
},
{
id: "5",
name: "Jane Cooper",
score: "37/50",
points: "987",
rank: "5",
program: "Graduate Program",
avatar: "/assets/avatar5.png"
},
{
id: "6",
name: "John Doe",
score: "35/50",
points: "982",
rank: "6",
program: "Graduate Program",
avatar: "/assets/avatar6.png"
},
{
id: "7",
name: "Alice",
score: "33/50",
points: "980",
rank: "7",
program: "Graduate Program",
avatar: "/assets/avatar1.png"
},
{
id: "8",
name: "Bob",
score: "32/50",
points: "978",
rank: "8",
program: "Graduate Program",
avatar: "/assets/avatar2.png"
},
{
id: "9",
name: "Charlie",
score: "30/50",
points: "975",
rank: "9",
program: "Graduate Program",
avatar: "/assets/avatar3.png"
},
{
id: "10",
name: "Diana",
score: "28/50",
points: "972",
rank: "10",
program: "Graduate Program",
avatar: "/assets/avatar4.png"
}
];
export default function QuizResult(){
const [resultData, setResultData] = useState<ResultData | null>(null);
useEffect(() => {
let urlParams = new URLSearchParams(window.location.search);
let quizIdValue = urlParams.get('id');
console.log(quizIdValue);
fetch(`http://localhost:5174/api/quizresult-aftersubmit?id=${quizIdValue}`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data.totalQuestions);
setResultData(data);
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
}, []); // Empty dependency array to run only once on mount
return (
<div>
<QuizHeader />
<div className='container mx-auto max-w-[890px] shadow-xl rounded-xl py-8 mb-8 border-[1px] border-[#DCDCDC] rounded-[10px] mt-[50px]'>
<button className="float-right absolute right-0 2xl:right-80 top-32 bg-[#9D9D9D] w-[45px] h-[45px] font-[700] text-[#FFF] text-[20px] rounded-full">&#10005;</button>
<div className='flex flex-col justify-center place-items-center space-y-4 py-6 px-10'>
<img src="/assets/celebration-icon.png" alt="" />
{resultData && (
<div className="flex flex-col justify-center place-items-center">
<p className='text-[24px] font-[700]'>{`You scored ${resultData.correctAnswers}/${resultData.totalQuestions}`}</p>
<p className='text-[20px] font-[500] text-[#525252]'>{resultData.message}</p>
</div>
)}
<a href="#" className='bg-[#000] text-[20px] font-[600] text-[#FFF] inline-flex place-items-center px-[50px] py-[15px] rounded-[10px]'><img src="/assets/reload.svg" alt="" /> &nbsp;Another Quiz</a>
</div>
<p className="text-[20px] font-[700] py-3 border-y-[1px] border-y-[#CFCFCF] px-10">Top Performers of this Quiz</p>
<div className="flex flex-col">
{
performersData.map((data) => (
<div key={data.id} className="flex flex-row justify-between place-items-center px-10 py-2.5 hover:bg-[#FDF2E7] duration-500">
<div className="flex flex-row space-x-6 place-items-center justify-center">
<p className="text-[14px] font-[700]"># {data.id}</p>
<img className="w-[50px] h-[50px]" src={data.avatar} alt="" />
<div className="flex flex-col">
<p className="text-[16px] font-[700]">{data.name}</p>
<p className="text-[12px] font-[500] text-[#6E6E6E]">{data.program}</p>
</div>
</div>
<div className="flex flex-col justify-center place-items-center">
<img className="w-[26px] h-[30px]" src="/assets/batch-icon.svg" alt="" />
<p className="text-[14px] font-[700]">{data.score}</p>
</div>
</div>
))
}
</div>
</div>
</div>
)
}

252
app/routes/quiz3.tsx Normal file
View File

@ -0,0 +1,252 @@
import { useState, useEffect } from 'react';
// Sample questions JSON data
// const questionsData = [
// {
// id: 1,
// question: "What is the capital of France?",
// options: ["Berlin", "Madrid", "Paris", "Rome"],
// answer: "Paris",
// },
// {
// id: 2,
// question: "Which planet is known as the Red Planet?",
// options: ["Earth", "Mars", "Jupiter", "Saturn"],
// answer: "Mars",
// },
// {
// id: 3,
// question: "What is the chemical symbol for gold?",
// options: ["Au", "Ag", "Pb", "Fe"],
// answer: "Au",
// },
// {
// id: 4,
// question: "Who wrote 'To Kill a Mockingbird'?",
// options: ["Harper Lee", "Mark Twain", "Ernest Hemingway", "J.K. Rowling"],
// answer: "Harper Lee",
// },
// {
// id: 5,
// question: "What is the largest ocean on Earth?",
// options: ["Atlantic Ocean", "Indian Ocean", "Arctic Ocean", "Pacific Ocean"],
// answer: "Pacific Ocean",
// },
// {
// id: 6,
// question: "Which element has the atomic number 1?",
// options: ["Helium", "Hydrogen", "Oxygen", "Carbon"],
// answer: "Hydrogen",
// },
// {
// id: 7,
// question: "In which year did the Titanic sink?",
// options: ["1912", "1905", "1898", "1923"],
// answer: "1912",
// },
// {
// id: 8,
// question: "Who is the author of '1984'?",
// options: ["George Orwell", "Aldous Huxley", "Ray Bradbury", "J.D. Salinger"],
// answer: "George Orwell",
// },
// {
// id: 9,
// question: "What is the hardest natural substance on Earth?",
// options: ["Gold", "Platinum", "Diamond", "Iron"],
// answer: "Diamond",
// },
// {
// id: 10,
// question: "What is the largest planet in our solar system?",
// options: ["Earth", "Saturn", "Neptune", "Jupiter"],
// answer: "Jupiter",
// },
// {
// id: 11,
// question: "What is the main ingredient in guacamole?",
// options: ["Tomato", "Avocado", "Pepper", "Onion"],
// answer: "Avocado",
// },
// {
// id: 12,
// question: "Which country is known as the Land of the Rising Sun?",
// options: ["China", "Japan", "Thailand", "South Korea"],
// answer: "Japan",
// },
// {
// id: 13,
// question: "What is the smallest prime number?",
// options: ["1", "2", "3", "5"],
// answer: "2",
// },
// {
// id: 14,
// question: "Who painted the Mona Lisa?",
// options: ["Vincent van Gogh", "Leonardo da Vinci", "Pablo Picasso", "Claude Monet"],
// answer: "Leonardo da Vinci",
// },
// {
// id: 15,
// question: "What is the capital city of Australia?",
// options: ["Sydney", "Melbourne", "Canberra", "Brisbane"],
// answer: "Canberra",
// },
// {
// id: 16,
// question: "Which gas do plants primarily use for photosynthesis?",
// options: ["Oxygen", "Nitrogen", "Carbon Dioxide", "Hydrogen"],
// answer: "Carbon Dioxide",
// },
// {
// id: 17,
// question: "What is the boiling point of water in Celsius?",
// options: ["90°C", "100°C", "110°C", "120°C"],
// answer: "100°C",
// },
// {
// id: 18,
// question: "Which language is primarily spoken in Brazil?",
// options: ["Spanish", "Portuguese", "French", "English"],
// answer: "Portuguese",
// },
// {
// id: 19,
// question: "What is the smallest unit of life?",
// options: ["Tissue", "Organ", "Cell", "Organism"],
// answer: "Cell",
// },
// {
// id: 20,
// question: "Who developed the theory of relativity?",
// options: ["Isaac Newton", "Galileo Galilei", "Albert Einstein", "Niels Bohr"],
// answer: "Albert Einstein",
// },
// {
// id: 21,
// question: "In what year did World War II end?",
// options: ["1945", "1944", "1946", "1943"],
// answer: "1945",
// },
// ];
interface QuizModule {
id: number;
question: string;
}
export default function Index() {
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const [timeRemaining, setTimeRemaining] = useState(60); // 60 seconds countdown
const [selectedAnswers, setSelectedAnswers] = useState<{ [key: number]: string }>({});
const [answeredQuestions, setAnsweredQuestions] = useState<{ id: number; selectedOption: string }[]>([]);
const [questionsData, setQuestionsData] = useState<QuizModule[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch(`http://localhost:5174/api/question-list`)
.then(res => {
if (!res.ok) {
throw new Error('Network response was not ok');
}
return res.json();
})
.then(data => {
// console.log('Question Data', typeof data);
setQuestionsData(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
// console.log('Question Data Length', questionsData.length)
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
useEffect(() => {
// Start the countdown timer
const id = setInterval(() => {
setTimeRemaining((prevTime) => {
if (prevTime <= 1) {
clearInterval(id);
return 0;
}
return prevTime - 1;
});
}, 1000);
// Clear interval on component unmount
return () => {
clearInterval(id);
};
}, []);
const handleNextQuestion = () => {
if (selectedAnswers[currentQuestion.id]) {
setAnsweredQuestions((prev) => [
...prev,
{ id: currentQuestion.id, selectedOption: selectedAnswers[currentQuestion.id] },
]);
}
setCurrentQuestionIndex((prevIndex) => (prevIndex + 1) % questionsData.length);
};
const handleAnswerChange = (questionId: number, selectedOption: string) => {
setSelectedAnswers((prevAnswers) => ({
...prevAnswers,
[questionId]: selectedOption,
}));
};
console.log('Question Data 04',questionsData)
const currentQuestion = questionsData[currentQuestionIndex];
console.log('Current Questions', currentQuestion);
return (
<>
<section className="container-fluid bg-[#000] ">
<div className="flex flex-row justify-center gap-x-8 py-6">
<p className="text-[42px] w-[42px] h-[31px]"></p>
<div className="flex flex-col justify-center place-items-center">
<p className="text-[#FFF] text-[24px] font-[700]"> Take an AI Generative Quiz</p>
<p className="text-[#FFF] text-[16px] font-[400]">Convert any text into an interactive quiz session</p>
</div>
</div>
</section>
<div className="mt-[100px]">{/* this div for margin top */}</div>
<div className="container mx-auto max-w-[890px]">
<p className="flex justify-end text-[20px] font-[600]">Time remaining: {timeRemaining} seconds</p>
</div>
<section id="" className="container mx-auto max-w-[890px] shadow-xl rounded-xl px-10 py-8 mb-8 border-[1px] border-[#DCDCDC] rounded-[10px] bg-[#FCFCFC]">
<div>
<h2 className="text-[32px] font-[700]">{`Q${currentQuestion.id}. ${currentQuestion.question}`}</h2>
{/* <div className="flex flex-col space-y-4 mt-8">
{currentQuestion.options.map((option, index) => (
<div key={index} className={`border-[1px] ${selectedAnswers[currentQuestion.id] === option ? 'border-[#000]' : 'border-[#D3D3D3]'} rounded-[10px] p-3 bg-[#FFF]`}>
<label className="text-[18px] font-[600]" htmlFor={`question${currentQuestion.id}_${index}`}>
<input type="radio" name={`question${currentQuestion.id}`} id={`question${currentQuestion.id}_${index}`} checked={selectedAnswers[currentQuestion.id] === option} onChange={() => handleAnswerChange(currentQuestion.id, option)}/>&nbsp;&nbsp;{option}</label>
</div>
))}
</div> */}
<div className="flex justify-end">
<button
className="bg-[#000] text-[#FFF] text-[18px] font-[600] rounded-[8px] px-[100px] py-[15px] mt-[50px] "
onClick={handleNextQuestion}
>
Next
</button>
</div>
</div>
</section>
{/* <pre>{JSON.stringify(answeredQuestions, null, 2)}</pre> */}
</>
);
}

229
app/routes/sample.tsx Normal file
View File

@ -0,0 +1,229 @@
import React, {useState} from 'react';
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined} from '@ant-design/icons';
import AdministrationIcon from '~/components/customIcon/AdministrationIcon';
import MyCoursesIcon from '~/components/customIcon/MyCoursesIcon';
import ExaminationIcon from '~/components/customIcon/ExaminationIcon';
import CommunityIcon from '~/components/customIcon/CommunityIcon';
import NotificationIcon from '~/components/customIcon/NotificationIcon';
import {Layout, Menu, theme, Button, Modal, MenuProps} from 'antd';
import { Dropdown, Space } from 'antd';
import '../../public/assets/left_side_nav.css';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items2: MenuProps['items'] = [
{
key: 'subsd1',
icon: <AdministrationIcon />,
label: (<p>&nbsp; Administration</p>),
children: [
{
key: '1sd',
label: (<a href='#'>Class Schedules</a>),
},
{
key: '2sd',
label: (<a href='#'>Classmate Directory</a>),
},
{
key: '3sd',
label: (<a href='#'>Qualifications</a>),
},
],
},
{
key: 'subsd2',
icon: <MyCoursesIcon />,
label: (<p>&nbsp; My Courses</p>),
children: [
{
key: '4sd',
label: (<a href='#'>Graduate Program</a>),
},
{
key: '5sd',
label: (<a href='#'>Post-Graduate Program</a>),
},
],
},
{
key: 'subsd3',
icon: <ExaminationIcon />,
label: (<p>&nbsp; Examinations</p>),
children: [
{
key: '6sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '7sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '8sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: 'subsd4',
icon: <CommunityIcon />,
label: (<p>&nbsp; Community</p>),
children: [
{
key: '9sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '10sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '11sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
{
key: 'subsd5',
icon: <NotificationIcon />,
label: (<p>&nbsp; Notifications</p>),
children: [
{
key: '12sd',
label: (<a href='#'>Exam Scheduled</a>),
},
{
key: '13sd',
label: (<a href='#'>Upcoming Exam</a>),
},
{
key: '14sd',
label: (<a href='#'>Passed Exam</a>),
},
],
},
// getItem('Files', '9', <FileOutlined />),
{
key: 'grp',
label: '',
type: 'group',
style: { marginTop: '100px' },
children: [
{
key: '15sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(SettingOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Settings</h2>)
},
{
key: '16sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(QuestionCircleOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Help & Support</h2>)
},
{
key: '17sd', style: {paddingTop: '10px', paddingBottom: '10px', border: 'none'},
icon: React.createElement(LogoutOutlined, { style: { color: '#000' } }),
label: (<h2 className='text-[18px] font-[700] text-[#000]'>Logout</h2>)
},
],
},
];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<Menu className='custom-menu' mode="inline" style={{ height: '100%', borderRight: 0, paddingTop: 30, background: 'transparent'}} items={items2} />
</Sider>
</div>
<Layout style={{marginLeft: 366, background: '#FFF'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<img src="../../assets/student-dash.svg" alt=""/>
<p className='pl-1 text-[18px] font-[700] whitespace-nowrap'>Student Dashboard</p>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="../../assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place Content from here */}
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

54
app/routes/sign-in.tsx Normal file
View File

@ -0,0 +1,54 @@
import { useState } from 'react';
import { FormEvent } from 'react';
export default function SignIn() {
const [userName, setUserName] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault(); // Prevent the default form submission
const data = {
userName,
password,
};
try {
const response = await fetch('http://localhost:5174/api/sign-in', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
console.log('Success:', result);
} catch (error) {
console.error('Error:', error);
}
};
return (
<section className="h-screen flex items-center justify-center">
<div className="container mx-auto px-4 max-w-xl">
<form onSubmit={handleSubmit} className="flex flex-col space-y-4 border-[1px] border-[#CFCFCF] rounded-[10px] shadow-lg py-10 px-6 ">
<div className="flex flex-col space-y-2">
<label htmlFor="userName">User Name:</label>
<input className="focus:outline-none border-[1px] focus:border-[#EF7A0C] p-2 rounded-[8px]" type="text" name="userName" id="userName" value={userName} onChange={(e) => setUserName(e.target.value)} />
</div>
<div className="flex flex-col space-y-2">
<label htmlFor="password">Password:</label>
<input className="focus:outline-none border-[1px] focus:border-[#EF7A0C] p-2 rounded-[8px]" type="password" name="password" id="password" value={password} onChange={(e) => setPassword(e.target.value)}/>
</div>
<label htmlFor="remember"><input type="checkbox" name="remember" id="remember" /> Remember Password</label>
<br />
<button className="bg-[#000] text-[#FFF] py-2.5 rounded-[8px]" type="submit" >Sign In</button>
</form>
</div>
</section>
);
}

View File

@ -1,81 +1,129 @@
import React, { useState } from 'react';
import {
DesktopOutlined,
FileOutlined,
PieChartOutlined,
TeamOutlined,
UserOutlined,
} from '@ant-design/icons';
import type { MenuProps } from 'antd';
import { Breadcrumb, Layout, Menu, theme } from 'antd';
import React, {useState} from 'react';
import { SettingOutlined, QuestionCircleOutlined, LogoutOutlined, RightOutlined} from '@ant-design/icons';
import AdministrationIcon from '~/components/customIcon/AdministrationIcon';
import MyCoursesIcon from '~/components/customIcon/MyCoursesIcon';
import ExaminationIcon from '~/components/customIcon/ExaminationIcon';
import CommunityIcon from '~/components/customIcon/CommunityIcon';
import NotificationIcon from '~/components/customIcon/NotificationIcon';
import ContunueLearning from '~/components/ContinueLearning';
import KnowledgeQuests from '~/components/KnowledgeQuests';
import TopPerformers from '~/components/TopPerformers';
import {Layout, Menu, theme, Button, Modal, MenuProps} from 'antd';
import { Dropdown, Space } from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Header, Content, Footer, Sider } = Layout;
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
function getItem(
label: React.ReactNode,
key: React.Key,
icon?: React.ReactNode,
children?: MenuItem[],
): MenuItem {
return {
key,
icon,
children,
label,
} as MenuItem;
}
const items: MenuItem[] = [
getItem('Option 1', '1', <PieChartOutlined />),
getItem('Option 2', '2', <DesktopOutlined />),
getItem('User', 'sub1', <UserOutlined />, [
getItem('Tom', '3'),
getItem('Bill', '4'),
getItem('Alex', '5'),
]),
getItem('Team', 'sub2', <TeamOutlined />, [getItem('Team 1', '6'), getItem('Team 2', '8')]),
getItem('Files', '9', <FileOutlined />),
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const App: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken();
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider theme="light" collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)}>
<div className="demo-logo-vertical" > IIMTT Logo </div>
<Menu theme="light" defaultSelectedKeys={['1']} mode="inline" items={items} > <span>Hi</span> </Menu>
</Sider>
<Layout>
<Header style={{ padding: 0, background: colorBgContainer }} />
<Content style={{ margin: '0 16px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>User</Breadcrumb.Item>
<Breadcrumb.Item>Bill</Breadcrumb.Item>
</Breadcrumb>
<div
style={{
padding: 24,
minHeight: 360,
background: colorBgContainer,
borderRadius: borderRadiusLG,
}}
>
Bill is a cat.
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
Ant Design ©{new Date().getFullYear()} Created by Ant UED
</Footer>
</Layout>
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: 366, background: '#FFF'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<img src="/assets/student-dash.svg" alt=""/>
<p className='pl-1 text-[18px] font-[700] whitespace-nowrap'>Student Dashboard</p>
</div>
<div>
<button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="/assets/notification-bell.svg" alt="" />
</div>
</button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
{/* Place content from here */}
<div>
<ContunueLearning />
</div>
<section className='container mx-auto my-16'>
<div className='grid grid-cols-1 xl:grid-cols-7 gap-y-6 border-[1px] border-[#CFCFCF]'>
<div className='xl:col-span-5 border-r-[1px] border-[#CFCFCF]'>
<KnowledgeQuests />
</div>
<div className='xl:col-span-2'>
<TopPerformers />
</div>
</div>
</section>
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default App;

View File

@ -1,10 +0,0 @@
import type { MetaFunction } from "@remix-run/node";
import StudentDashboard from '../components/StudentDashboard'
export default function Index() {
return (
<div>
<StudentDashboard /> {/* Ensure the component name matches the import */}
</div>
);
}

View File

113
app/routes/theory.mod1.tsx Normal file
View File

@ -0,0 +1,113 @@
import React, {useState} from 'react';
import { RightOutlined} from '@ant-design/icons';
import StartCourse from '~/components/MyCourseTheoryModule';
import {Layout, theme, Button, MenuProps, Breadcrumb, Dropdown, Space} from 'antd';
import '../../public/assets/left_side_nav.css';
import LeftSideMenu from '~/components/LeftSideMenuItems';
const { Content, Sider } = Layout;
const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
key,
label: `navsd ${key}`,
}));
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: <a href="https://www.antgroup.com">1st menu item</a>,
key: '01sd',
},
{
type: 'divider',
},
{
label: <a href="https://www.aliyun.com">2nd menu item</a>,
key: '02sd',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '03sd',
},
];
const Course: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 100);
};
const { token: { colorBgContainer}, } = theme.useToken();
return (
<Layout>
<Layout>
<div >
<Sider collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)} width={366} style={{overflow: 'auto', height: '110vh', position: 'fixed', left: 0, top: 0, bottom: 0, background: '#FFF', borderRight: '1px solid #CFCFCF', borderBottom: '2px solid #000'}}>
<div className='flex flex-col justify-center demo-logo-vertical'>
<div className='px-4'>
<h1 className='text-[22px] font-[700] my-[37px] text-left text-[#000]'>IIMTT Logo</h1>
</div>
</div>
<LeftSideMenu />
</Sider>
</div>
<Layout style={{marginLeft: collapsed ? 80 : 366, background: '#FFF', transition: 'margin-left 0.2s ease'}}>
<Content style={{ overflow: 'initial',}}>
<div className='border-b-[1px] py-2 border-[#CFCFCF]'>
<div className='container mx-auto flex flex-row justify-between pr-8'>
<div className='inline-flex justify-center place-items-center'>
<Breadcrumb separator=">" className='pl-6' style={{fontSize: '18px' , fontWeight: '700'}} items={[{title: <a href="/mycourse">Course</a>,},{title: <a href="/mycourse/theory">Theory</a>,},{title: 'Module 1 : Life History of Dr. Maria Montessori'}]}/>
</div>
<div>
<Button className='border-none shadow-none bg-transparent hover:bg-transparent' onClick={showLoading}>
<div className='border-[1px] border[#525252] rounded-full p-2 w-[47px] h-[47px]'>
<img src="../../assets/notification-bell.svg" alt="" />
</div>
</Button>
<Dropdown menu={{ items }} trigger={['click']}>
<a onClick={(e) => e.preventDefault()}>
<Space>
<div className='flex flex-row border-[1px] border-[#BBBBBB] rounded-full p-1 gap-x-6'>
<img src="/assets/man.png" alt="" />
<div>
<p className='text-[12px] text-[#EF7A0C] font-[500]'>My Profile</p>
<p className='text-[16px] text-[#27549F] font-[700]'>Rayan Holiday</p>
</div>
<RightOutlined style={{ fontSize: '12px', paddingRight: '10px' }} />
</div>
</Space>
</a>
</Dropdown>
</div>
</div>
</div>
<div className=''>
<StartCourse />
</div>
{/* Place Content from here */}
</Content>
</Layout>
</Layout>
</Layout>
);
};
export default Course;

BIN
public/assets/aimage1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
public/assets/aimage2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
public/assets/aimage3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
public/assets/aimage4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
public/assets/aimage5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@ -0,0 +1,3 @@
<svg width="22" height="25" viewBox="0 0 22 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.7278 14.7331C10.3856 14.7331 10.0985 14.6174 9.86656 14.3859C9.63457 14.1544 9.51857 13.8675 9.51857 13.5253C9.51857 13.1831 9.63431 12.896 9.8658 12.664C10.0973 12.4321 10.3842 12.3161 10.7264 12.3161C11.0686 12.3161 11.3557 12.4318 11.5876 12.6633C11.8196 12.8948 11.9356 13.1816 11.9356 13.5239C11.9356 13.8661 11.8199 14.1531 11.5884 14.3851C11.3569 14.6171 11.07 14.7331 10.7278 14.7331ZM6.06115 14.7331C5.71895 14.7331 5.43186 14.6174 5.19989 14.3859C4.9679 14.1544 4.85191 13.8675 4.85191 13.5253C4.85191 13.1831 4.96765 12.896 5.19913 12.664C5.43064 12.4321 5.71749 12.3161 6.0597 12.3161C6.4019 12.3161 6.68899 12.4318 6.92096 12.6633C7.15295 12.8948 7.26895 13.1816 7.26895 13.5239C7.26895 13.8661 7.1532 14.1531 6.92172 14.3851C6.69021 14.6171 6.40336 14.7331 6.06115 14.7331ZM15.3945 14.7331C15.0588 14.7331 14.7733 14.6174 14.5381 14.3859C14.3029 14.1544 14.1852 13.8675 14.1852 13.5253C14.1852 13.1831 14.3026 12.896 14.5374 12.664C14.7721 12.4321 15.0585 12.3161 15.3965 12.3161C15.7345 12.3161 16.02 12.4318 16.2529 12.6633C16.4858 12.8948 16.6023 13.1816 16.6023 13.5239C16.6023 13.8661 16.4865 14.1531 16.2551 14.3851C16.0235 14.6171 15.7367 14.7331 15.3945 14.7331ZM10.7278 19.3998C10.3856 19.3998 10.0985 19.2824 9.86656 19.0476C9.63457 18.8129 9.51857 18.5265 9.51857 18.1885C9.51857 17.8505 9.63431 17.565 9.8658 17.3321C10.0973 17.0992 10.3842 16.9827 10.7264 16.9827C11.0686 16.9827 11.3557 17.0985 11.5876 17.33C11.8196 17.5615 11.9356 17.8483 11.9356 18.1905C11.9356 18.5262 11.8199 18.8117 11.5884 19.0469C11.3569 19.2821 11.07 19.3998 10.7278 19.3998ZM6.06115 19.3998C5.71895 19.3998 5.43186 19.2824 5.19989 19.0476C4.9679 18.8129 4.85191 18.5265 4.85191 18.1885C4.85191 17.8505 4.96765 17.565 5.19913 17.3321C5.43064 17.0992 5.71749 16.9827 6.0597 16.9827C6.4019 16.9827 6.68899 17.0985 6.92096 17.33C7.15295 17.5615 7.26895 17.8483 7.26895 18.1905C7.26895 18.5262 7.1532 18.8117 6.92172 19.0469C6.69021 19.2821 6.40336 19.3998 6.06115 19.3998ZM15.3945 19.3998C15.0588 19.3998 14.7733 19.2824 14.5381 19.0476C14.3029 18.8129 14.1852 18.5265 14.1852 18.1885C14.1852 17.8505 14.3026 17.565 14.5374 17.3321C14.7721 17.0992 15.0585 16.9827 15.3965 16.9827C15.7345 16.9827 16.02 17.0985 16.2529 17.33C16.4858 17.5615 16.6023 17.8483 16.6023 18.1905C16.6023 18.5262 16.4865 18.8117 16.2551 19.0469C16.0235 19.2821 15.7367 19.3998 15.3945 19.3998ZM2.03986 24.1989C1.50321 24.1989 1.03786 24.0019 0.643797 23.6079C0.249755 23.2138 0.0527344 22.7485 0.0527344 22.2118V4.25401C0.0527344 3.71546 0.249755 3.24847 0.643797 2.85305C1.03786 2.45761 1.50321 2.25989 2.03986 2.25989H3.87293V1.50602C3.87293 1.23226 3.9698 0.997797 4.16354 0.802634C4.35727 0.60747 4.59288 0.509888 4.87037 0.509888C5.15614 0.509888 5.39708 0.60747 5.59318 0.802634C5.78927 0.997797 5.88732 1.23226 5.88732 1.50602V2.25989H15.5669V1.50602C15.5669 1.23226 15.6637 0.997797 15.8575 0.802634C16.0512 0.60747 16.2868 0.509888 16.5643 0.509888C16.8501 0.509888 17.091 0.60747 17.2871 0.802634C17.4832 0.997797 17.5813 1.23226 17.5813 1.50602V2.25989H19.4143C19.9529 2.25989 20.4199 2.45761 20.8153 2.85305C21.2107 3.24847 21.4085 3.71546 21.4085 4.25401V22.2118C21.4085 22.7485 21.2107 23.2138 20.8153 23.6079C20.4199 24.0019 19.9529 24.1989 19.4143 24.1989H2.03986ZM2.03986 22.2118H19.4143V9.73291H2.03986V22.2118Z" fill="#EF7A0C"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

3
public/assets/cart.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="24" height="23" viewBox="0 0 24 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.65267 17.7309V20.4277H21.8005V17.7309H2.65267ZM2.65267 22.358C2.12394 22.358 1.67073 22.1688 1.29306 21.7903C0.915397 21.4118 0.726562 20.9576 0.726562 20.4277V6.91545C0.726562 6.38556 0.915397 5.93137 1.29306 5.55287C1.67073 5.17438 2.12394 4.98513 2.65267 4.98513H5.96671C5.89118 4.81481 5.82036 4.6019 5.75427 4.34642C5.68818 4.09094 5.65513 3.85911 5.65513 3.65094C5.65513 2.74255 5.97615 1.96663 6.61819 1.32319C7.26022 0.679753 8.025 0.358032 8.91252 0.358032C9.49791 0.358032 10.0408 0.504699 10.5412 0.798032C11.0416 1.09137 11.4429 1.47459 11.745 1.94771L12.2549 2.71416L12.7364 1.94771C13.0574 1.45567 13.454 1.06771 13.9261 0.783839C14.3982 0.499968 14.9174 0.358032 15.484 0.358032C16.4092 0.358032 17.1929 0.675021 17.8349 1.309C18.477 1.94298 18.798 2.72362 18.798 3.65094C18.798 3.85911 18.7744 4.06728 18.7272 4.27545C18.68 4.48362 18.6092 4.72018 18.5147 4.98513H21.8005C22.3292 4.98513 22.7824 5.17438 23.1601 5.55287C23.5377 5.93137 23.7266 6.38556 23.7266 6.91545V20.4277C23.7266 20.9576 23.5377 21.4118 23.1601 21.7903C22.7824 22.1688 22.3292 22.358 21.8005 22.358H2.65267ZM2.65267 14.5516H21.8005V6.91545H14.9458L17.1835 10.038C17.3156 10.2462 17.3581 10.4638 17.3109 10.6909C17.2637 10.918 17.1551 11.1167 16.9852 11.2871C16.7775 11.4385 16.5509 11.5 16.3054 11.4716C16.0599 11.4432 15.8616 11.3249 15.7106 11.1167L12.2266 6.20577L8.68592 11.1167C8.53486 11.3249 8.33658 11.4479 8.09109 11.4858C7.84561 11.5236 7.64733 11.4574 7.49627 11.2871C7.28855 11.1357 7.17053 10.9464 7.1422 10.7193C7.11388 10.4922 7.16581 10.2651 7.29799 10.038L9.50735 6.91545H2.65267V14.5516ZM8.94085 5.15545C9.35628 5.15545 9.71035 5.00879 10.003 4.71545C10.2957 4.42212 10.4421 4.06728 10.4421 3.65094C10.4421 3.23459 10.2957 2.87975 10.003 2.58642C9.71035 2.29309 9.35628 2.14642 8.94085 2.14642C8.52541 2.14642 8.17135 2.29309 7.87866 2.58642C7.58596 2.87975 7.43962 3.23459 7.43962 3.65094C7.43962 4.06728 7.58596 4.42212 7.87866 4.71545C8.17135 5.00879 8.52541 5.15545 8.94085 5.15545ZM15.484 5.15545C15.9183 5.15545 16.2818 5.00879 16.5745 4.71545C16.8672 4.42212 17.0135 4.06728 17.0135 3.65094C17.0135 3.23459 16.8672 2.87975 16.5745 2.58642C16.2818 2.29309 15.9183 2.14642 15.484 2.14642C15.0874 2.14642 14.7428 2.29309 14.4501 2.58642C14.1574 2.87975 14.011 3.23459 14.011 3.65094C14.011 4.06728 14.1574 4.42212 14.4501 4.71545C14.7428 5.00879 15.0874 5.15545 15.484 5.15545Z" fill="#EF7A0C"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,24 @@
.custom-radio {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 29.47px;
height: 29.47px;
border: 2px solid #ccc;
border-radius: 50%;
position: relative;
}
/* Create the inner circle for checked state */
.custom-radio:checked::before {
content: '';
display: block;
width: 12.74px;
height: 12.74px;
background-color: #000;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

BIN
public/assets/gimage1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

BIN
public/assets/gimage10.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
public/assets/gimage11.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

BIN
public/assets/gimage12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
public/assets/gimage2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
public/assets/gimage3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
public/assets/gimage4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
public/assets/gimage5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
public/assets/gimage6.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

BIN
public/assets/gimage7.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
public/assets/gimage8.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
public/assets/gimage9.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

View File

@ -0,0 +1,3 @@
<svg width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.55925 12.1912L13.4342 6.3162L12.2676 5.14954L7.55925 9.85787L5.18425 7.48287L4.01758 8.64954L7.55925 12.1912ZM8.72591 16.6912C7.57313 16.6912 6.4898 16.4725 5.47591 16.035C4.46202 15.5975 3.58008 15.0037 2.83008 14.2537C2.08008 13.5037 1.48633 12.6218 1.04883 11.6079C0.611328 10.594 0.392578 9.51065 0.392578 8.35787C0.392578 7.20509 0.611328 6.12176 1.04883 5.10787C1.48633 4.09398 2.08008 3.21204 2.83008 2.46204C3.58008 1.71204 4.46202 1.11829 5.47591 0.680786C6.4898 0.243286 7.57313 0.0245361 8.72591 0.0245361C9.87869 0.0245361 10.962 0.243286 11.9759 0.680786C12.9898 1.11829 13.8717 1.71204 14.6217 2.46204C15.3717 3.21204 15.9655 4.09398 16.403 5.10787C16.8405 6.12176 17.0592 7.20509 17.0592 8.35787C17.0592 9.51065 16.8405 10.594 16.403 11.6079C15.9655 12.6218 15.3717 13.5037 14.6217 14.2537C13.8717 15.0037 12.9898 15.5975 11.9759 16.035C10.962 16.4725 9.87869 16.6912 8.72591 16.6912Z" fill="#218B32"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
public/assets/image1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
public/assets/image2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
public/assets/image3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
public/assets/limage1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
public/assets/limage10.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/assets/limage11.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
public/assets/limage12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/assets/limage2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/assets/limage3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show More