Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/T4910/OctaView
Browse files Browse the repository at this point in the history
  • Loading branch information
Emmy-Akintz committed Apr 23, 2024
2 parents 554ac04 + fed6df6 commit 9f1a3ad
Show file tree
Hide file tree
Showing 22 changed files with 728 additions and 235 deletions.
35 changes: 21 additions & 14 deletions src/components/admin/new-timetable-config/Index.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import TimeTable from '@/components/timetable'
import DisplayAI from "./aiTImetable"
import Details from '@/components/admin/new-timetable-config/details'
import { useState } from 'react';
import Defaults from '../settings/defaults'

import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"

// TODO:
// Cool loading component that covers the timetable form creator

const Index = () => {
const [schedule, setSchedule] = useState({});


return (
<div className='mx-auto p-8 mt-3 md:via-slate-50 lg:via-white sm: max-w-[56rem] space-y-4'>
<div className="mx-auto grid w-full max-w-6xl gap-1">
<h1 className="text-xl font-semibold">Create new timetable</h1>
<div>
<Card className="max-w-[60rem] mt-10 mx-auto">
<CardHeader>
<CardTitle className="text-xl font-semibold">Create new timetable</CardTitle>
<CardDescription>
<p>Timetable is created by a scheduling algorithm which uses all the saved courses and priority.</p>
<p>Want to start from an existing timetable template? <span className='underline text-blue-500'>Import previous timetables</span></p>
</div>
</div>
<div>
<Details setSchedule={setSchedule}/>
<Defaults />
</div>
{!!schedule?.startDay ? <TimeTable schedule={schedule}/> : null}
</div>
</CardDescription>
</CardHeader>
<CardContent className="min-h-fit">
{!!schedule?.startDay ? <DisplayAI schedule={schedule}/> : <Details setSchedule={setSchedule}/>}
{/* <Details setSchedule={setSchedule}/> */}
</CardContent>
</Card>
)
};

Expand Down
38 changes: 38 additions & 0 deletions src/components/admin/new-timetable-config/aiTImetable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Timetable from '../../timetable'
import { Skeleton } from '@/components/ui/skeleton';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"


export default function dispalyAITimetable({ schedule }) {

return (
<Card className='mt-6 md:via-slate-50 lg:via-white space-y-6'>
<CardHeader className='flex justify-between items-center space-x-3'>
<div className="mx-auto grid w-full max-w-6xl gap-1">
<h1 className="text-2xl font-semibold">
{(!!schedule?.name)
? (schedule?.name??'Timetable Name')
: <Skeleton className="max-w-64 h-8"/>}
</h1>
<div>
<p className='font-medium text-sm text-muted-foreground'>
{(!!schedule?.description)
? (schedule?.description??'Timetable Name')
: (schedule?.description === "") ? null : <Skeleton className="w-52 h-5"/>}
</p>
</div>
</div>
</CardHeader>
<CardContent>
<Timetable schedule={schedule}/>
</CardContent>
</Card>
)
}
145 changes: 99 additions & 46 deletions src/components/admin/new-timetable-config/createTimetableBtn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,66 @@ import { useState } from 'react'

const serverLink = import.meta.env.VITE_SERVER_LINK

export default function createTimetableBtn({setSchedule, details, ...neededDetails}) {
export default function createTimetableBtn({setSchedule, details}) {
const [loading, setLoading] = useState(false)
const [anerror, setAnerror] = useState(false)
const date = new Date()

return (
<Button
disabled={loading}
onClick={async () => {
let gptJSON, timeslotSchedule;
console.log(details)
console.log(details, 32939832)
const {name, description, current, examMode, interval, startTime,
endTime, currentYear, startDay, endDay, semester, level, selectedDepartment, allDepartments} = details

setAnerror(false)
setLoading(true);

const departmentsToBeEntered = (selectedDepartment === 'all') ? allDepartments : allDepartments.find(department => department.code === selectedDepartment)
let coursesForAI = []

console.log('filtering courses to be used')
for (let index = 0; index < departmentsToBeEntered.length; index++) {
const department = departmentsToBeEntered[index];

const response = await axios.post(`${serverLink}/course/get-course`, (level === 'all') ? {departmentId: department._id} : { departmentId: department._id, level });

coursesForAI = [...coursesForAI, ...response?.data?.courses]
}

const departmentRes = await axios.post(`${serverLink}/department/get-department`, {});
const venueRes = await axios.post(`${serverLink}/venue/get-venue`, {});

coursesForAI = coursesForAI.map(course => course.code)

let departmentsForAI = departmentRes?.data?.department?.map(department => department.name)
let venuesForAI = venueRes?.data?.venue?.map(venue => venue.name)


const promptDetails = {
courses: turnArrayDirectlyToString(coursesForAI),
venues: turnArrayDirectlyToString(venuesForAI),
departments: turnArrayDirectlyToString(departmentsForAI)
}
console.log(promptDetails, 823832)

// get courses in each department
// setLoading(false)

try {
console.log('asking gpt')
gptJSON = await askGPT(neededDetails);

gptJSON = await askGPT(details, promptDetails);

console.log('gpt response', gptJSON, '\npopulatin json...')
timeslotSchedule = await convertToCleanSchedule(gptJSON);
} catch (error) {
console.log('Error in creating timetable: ', error)
setLoading(false)
setAnerror(true)
return
}

// if(!(!!timeslotSchedule?.csc)){
Expand All @@ -37,13 +77,13 @@ export default function createTimetableBtn({setSchedule, details, ...neededDetai

const schedule = {
id: '78654678',
semester: 'alpha',
startDay: 'monday',
endDay: 'friday',
name: 'GPT created',
description: '',
year: '2023/2024',
mode: 'exam', // or Exam
semester,
startDay: startDay??'monday',
endDay: endDay??'friday',
name: name??date.toLocaleString().split(',').toString().replace(',',''),
description,
year: currentYear,
mode: examMode ? 'exam' : 'classes', // or Exam
lectureHours: {
startHour: '2010-01-01T08:00:00.000Z',
endHour: '2010-01-01T18:00:00.000Z'
Expand All @@ -54,11 +94,11 @@ export default function createTimetableBtn({setSchedule, details, ...neededDetai
console.log('schedule that is being set: ', schedule)
setSchedule(schedule);
setLoading(false)
}}>Create</Button>
}}>{anerror ?'Retry' : 'Create'}</Button>
)
}

async function askGPT({ courses, departments, venues, startTime, endTime, interval, breakTime }){
async function askGPT({ courses, departments, venues, startTime, endTime, interval, breakTime }, promptDetails){
let prompt = `
Before you start reading the prompt, be FLEXIBLE with the format of details given!!!, DO NOT return the details given as a response, unless you state the problem and reason & any response you submit MUST be in a JSON format!!!!
The instructions are simple and possiblefor you to do
Expand All @@ -70,7 +110,7 @@ async function askGPT({ courses, departments, venues, startTime, endTime, interv
I will enter a list of courses in an array, departments in an array, venues in an array and the time contraints i.e the time to start inputting the activites of the day usually by 8:00 unless specified something else, time to end the activites of the day usually by 18:00 unless specified something else, time for a break, and the interval to which you'll be working with
####
Once you are done with your scheduling, I want you to only return your answer in a JSON format and output as your response just the JSON, nothing else, following this pattern:
Once you are done with your scheduling, I want you to only return your SCHEDULED answer in a JSON format and output as your response just the JSON, nothing else, following this pattern:
Your response should only be on what you have scheduled
[
Expand All @@ -86,9 +126,9 @@ async function askGPT({ courses, departments, venues, startTime, endTime, interv
#####
const courses = ['CSC 222', 'CSC 227', 'CSC 212'];
const departments = ['Computer Science', 'Mathematics'];
const venues = ['LT1', 'LT2', 'B01'];
const courses = ${promptDetails.courses};
const departments = ${promptDetails.departments};
const venues = ${promptDetails.venues};
const startTime = '8:00';
const endTime = '18:00';
const interval = 60; // in minutes
Expand All @@ -102,7 +142,10 @@ async function askGPT({ courses, departments, venues, startTime, endTime, interv
- Courses can only repeat once in the schedule
- AND MOST IMPORTANT RULE OF ALL: output ONLY JSON as your response, NOTHING ELSE!!!
`

console.log(prompt)
let response = await gpt.ask(prompt);
console.log('gpt response:', response)
const cleanedJSON = parseAndRemoveJsonTags(response)
return cleanedJSON;
}
Expand All @@ -120,12 +163,12 @@ async function convertToCleanSchedule(input) {

try{
for (const course of input) {
const code = course.course.split(' ')[0].toLowerCase();
// const code = course.course.split(' ')[0].toLowerCase();

const response = await axios.post(`${serverLink}/course/get-course`, { code: course.course });
const department = code // response?.data?.courses[0]?.departmentId?.code;
const department = response?.data?.courses[0]?.departmentId?.code;

console.log('Original departmental code: ', response?.data?.courses[0]?.departmentId?.code, 1111122222111)

const courseNumber = course.course.split(' ')[1];
const departmentNumber = Math.floor(parseInt(courseNumber) / 100) * 100;

Expand Down Expand Up @@ -164,31 +207,41 @@ async function convertToCleanSchedule(input) {
return output;
}

function turnArrayDirectlyToString(array){
const stringWithSingleQuotes = JSON.stringify(array, (key, value) => {
if (typeof value === 'string') {
return `'${value}'`;
}
return value;
});

return stringWithSingleQuotes;
}

// Example usage:
const input = [
{
"course": "CSC 222",
"day": "Monday",
"startTime": "2024-04-22T08:00:00",
"endTime": "2024-04-22T09:00:00",
"venue": "B12"
},
{
"course": "CSC 241",
"day": "Monday",
"startTime": "2024-04-22T09:00:00",
"endTime": "2024-04-22T10:00:00",
"venue": "B13"
},
{
"course": "CSC 141",
"day": "Monday",
"startTime": "2024-04-22T09:00:00",
"endTime": "2024-04-22T10:00:00",
"venue": "B12"
},
];

const output = async () => await convertToCleanSchedule(input);
console.log(JSON.stringify(output(), null, 2), 8787); // To print the output JSON with indentation
// // Example usage:
// const input = [
// {
// "course": "CSC 222",
// "day": "Monday",
// "startTime": "2024-04-22T08:00:00",
// "endTime": "2024-04-22T09:00:00",
// "venue": "B12"
// },
// {
// "course": "CSC 241",
// "day": "Monday",
// "startTime": "2024-04-22T09:00:00",
// "endTime": "2024-04-22T10:00:00",
// "venue": "B13"
// },
// {
// "course": "CSC 141",
// "day": "Monday",
// "startTime": "2024-04-22T09:00:00",
// "endTime": "2024-04-22T10:00:00",
// "venue": "B12"
// },
// ];

// const output = async () => await convertToCleanSchedule(input);
// console.log(JSON.stringify(output(), null, 2), 8787); // To print the output JSON with indentation
Loading

0 comments on commit 9f1a3ad

Please sign in to comment.