Skip to content

Commit

Permalink
Merge pull request #49 from avantifellows/feat/fetch-lc-and-sessions-…
Browse files Browse the repository at this point in the history
…from-session-occurrences

Feat: Fetch lc and quiz from session occurrences
  • Loading branch information
Bahugunajii authored Jul 29, 2024
2 parents a67d0d3 + 2c8f613 commit 2f798e2
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 59 deletions.
11 changes: 5 additions & 6 deletions api/afdb/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@ import getFetchConfig from '../fetchConfig';
const url = process.env.AF_DB_SERVICE_URL;
const bearerToken = process.env.AF_DB_SERVICE_BEARER_TOKEN || '';

export const getSessionSchedule = async (sessionId: number, batchId?: number) => {
export const getSessionOccurrences = async (sessionId: string) => {
try {
const queryParams = new URLSearchParams();
if (sessionId !== undefined) queryParams.append('session_id', sessionId.toString());
if (batchId !== undefined) queryParams.append('batch_id', batchId.toString());
const urlWithParams = `${url}/session-schedule?${queryParams.toString()}`;
const urlWithParams = `${url}/session-occurrence?${queryParams.toString()}&is_start_time=today`;
const response = await fetch(urlWithParams, getFetchConfig(bearerToken));

if (!response.ok) {
throw new Error(`Error in fetching Session Schedule Details: ${response.statusText}`);
throw new Error(`Error in fetching Session Occurrence Details: ${response.statusText}`);
}

const data = await response.json();
return data[0];
return data;
} catch (error) {
console.error("Error in fetching Session Schedule Details:", error);
console.error("Error in fetching Session Occurrence Details:", error);
throw error;
}
};
Expand Down
66 changes: 29 additions & 37 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
import { useAuth } from "@/services/AuthContext";
import TopBar from "@/components/TopBar";
import BottomNavigationBar from "@/components/BottomNavigationBar";
import { getSessionSchedule, fetchUserSession } from "@/api/afdb/session";
import { getSessionOccurrences, fetchUserSession } from "@/api/afdb/session";
import { useState, useEffect } from "react";
import { QuizSession, SessionSchedule, MessageDisplayProps, Session } from "./types";
import { QuizSession, SessionOccurrence, MessageDisplayProps, Session } from "./types";
import Link from "next/link";
import PrimaryButton from "@/components/Button";
import Loading from "./loading";
import { formatCurrentTime, formatSessionTime, formatQuizSessionTime, formatTime, isSessionActive, format12HrQuizSessionTime } from "@/utils/dateUtils";
import { formatCurrentTime, formatSessionTime, formatQuizSessionTime, formatTime, isSessionActive, format12HrSessionTime } from "@/utils/dateUtils";
import { api } from "@/services/url";
import { MixpanelTracking } from "@/services/mixpanel";

export default function Home() {
const { loggedIn, userId, userDbId } = useAuth();
const [liveClasses, setLiveClasses] = useState<SessionSchedule[]>([]);
const [liveClasses, setLiveClasses] = useState<SessionOccurrence[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [quizzes, setQuizzes] = useState<QuizSession[]>([]);
const commonTextClass = "text-gray-700 text-xs md:text-sm mx-3 md:mx-8 whitespace-nowrap w-12";
Expand All @@ -24,35 +24,27 @@ export default function Home() {

const fetchUserSessions = async () => {
try {
const currentDay = (new Date().getDay() + 6) % 7 + 1;

const [liveSessionData, quizSessionData] = await Promise.all([
fetchUserSession(userDbId!),
fetchUserSession(userDbId!, true)
]);

const filteredQuizSessions = quizSessionData.filter((quiz: Session) => {
const { is_active: isActive, repeat_schedule: repeatSchedule } = quiz;
return isActive && repeatSchedule &&
repeatSchedule.type === 'weekly' &&
repeatSchedule.params.includes(currentDay);
}).filter(Boolean);

const quizSessions = filteredQuizSessions.filter((session: Session) => session.platform === 'quiz');
const quizData = await Promise.all(quizSessionData.map(async (quiz: Session) => {
const sessionOccurrenceData = await getSessionOccurrences(quiz.session_id);
if (!sessionOccurrenceData) return null;
return sessionOccurrenceData;
}));
const flattenedQuizData = quizData.flat();
const quizSessions = flattenedQuizData.filter(flattenedSessionsData => flattenedSessionsData.session.platform === 'quiz');
setQuizzes(quizSessions);

const sessionsData = await Promise.all(liveSessionData.map(async (liveSession: Session) => {
const sessionScheduleData = await getSessionSchedule(liveSession.id);
if (!sessionScheduleData) return null;

const { is_active: isActive, repeat_schedule: repeatSchedule } = sessionScheduleData.session;
return isActive && repeatSchedule &&
repeatSchedule.type === 'weekly' &&
repeatSchedule.params.includes(currentDay) ? sessionScheduleData : null;
const sessionOccurrenceData = await getSessionOccurrences(liveSession.session_id);
if (!sessionOccurrenceData) return null;
return sessionOccurrenceData;
}));

const liveSessions = sessionsData.filter(sessionSchedule => sessionSchedule)
.filter(sessionSchedule => sessionSchedule.session.platform === 'meet');
const flattenedSessionsData = sessionsData.flat();
const liveSessions = flattenedSessionsData.filter(flattenedSessionsData => flattenedSessionsData.session.platform === 'meet');

setLiveClasses(liveSessions);
MixpanelTracking.getInstance().identify(userId!);
Expand Down Expand Up @@ -102,7 +94,7 @@ export default function Home() {
return (
<p className="text-xs italic font-normal mr-4">
Starts at <br />
{format12HrQuizSessionTime(data.start_time)}
{format12HrSessionTime(data.start_time)}
</p>
);
}
Expand Down Expand Up @@ -141,20 +133,20 @@ export default function Home() {
<Loading />
</div>
) : (
<main className="min-h-screen max-w-xl mx-auto md:mx-auto bg-white">
<main className="min-h-screen max-w-xl mx-auto md:mx-auto bg-heading">
<TopBar />
<div className="bg-heading">
<div>
<h1 className="text-primary ml-4 font-semibold text-xl pt-6">Live Classes</h1>
{liveClasses.length > 0 ? (
<div className="grid grid-cols-1 gap-4 pb-16">
{liveClasses.map((data, index) => (isSessionActive(formatSessionTime(data.end_time)) &&
<div key={index} className="flex mt-4 items-center" >
<div>
<p className={`${commonTextClass}`}>
{formatTime(data.start_time)}
{format12HrSessionTime(data.start_time)}
</p>
<p className={`${commonTextClass}`}>
{formatTime(data.end_time)}
{format12HrSessionTime(data.end_time)}
</p>
</div>
<div className="bg-white rounded-lg shadow-lg min-h-24 h-auto py-6 relative w-full flex flex-row justify-between mr-4 items-center">
Expand All @@ -176,35 +168,35 @@ export default function Home() {
<MessageDisplay message="No more live classes are scheduled for today!" />
)}
</div>
<div className="bg-heading">
<div>
<h1 className="text-primary ml-4 font-semibold text-xl">Tests</h1>
{quizzes.length > 0 ? (
<div className="grid grid-cols-1 gap-4 pb-40">
{quizzes.map((data, index) => (isSessionActive(formatQuizSessionTime(data.end_time)) &&
{quizzes.map((data, index) => (isSessionActive(formatQuizSessionTime(data.session.end_time)) &&
<div key={index} className="flex mt-4 items-center" >
<div>
<p className={`${commonTextClass}`}>
{format12HrQuizSessionTime(data.start_time)}
{format12HrSessionTime(data.session.start_time)}
</p>
<p className={`${commonTextClass}`}>
{format12HrQuizSessionTime(data.end_time)}
{format12HrSessionTime(data.session.end_time)}
</p>
</div>
<div className="bg-white rounded-lg shadow-lg min-h-24 h-auto py-6 relative w-full flex flex-row justify-between mr-4 items-center">
<div className={`${index % 2 === 0 ? 'bg-orange-200' : 'bg-red-200'} h-full w-2 absolute left-0 top-0 rounded-s-md`}></div>
<div className="text-sm md:text-base mx-6 md:mx-8">
<div className="flex w-36">
<span className="font-semibold">{data.name}</span>
<span className="font-semibold">{data.session.name}</span>
</div>
<div className="text-sm md:text-base">
<span>{data.meta_data.test_format}</span>
<span>{data.session.meta_data.test_format}</span>
</div>
</div>
{renderButton(data)}
{renderButton(data.session)}
</div>
</div>
))}
{quizzes.filter((data) => isSessionActive(formatQuizSessionTime(data.end_time))).length === 0 && (
{quizzes.filter((data) => isSessionActive(formatQuizSessionTime(data.session.end_time))).length === 0 && (
<MessageDisplay message="No more tests are scheduled for today!" />
)}
</div>) : (
Expand Down
33 changes: 18 additions & 15 deletions app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ export interface Session {
repeat_schedule: {
type: string;
params: Object[];
}
},
session_id: string;
}

export interface ReportsListProps {
Expand Down Expand Up @@ -119,20 +120,22 @@ export interface Teacher {
}

export interface QuizSession {
batch: string,
end_date: string,
end_time: string,
meta_data: {
test_format: string
}
start_date: string,
start_time: string,
name: string,
subject: string,
id: string,
}

export interface SessionSchedule {
session: {
batch: string,
end_date: string,
end_time: string,
meta_data: {
test_format: string
}
start_date: string,
start_time: string,
name: string,
subject: string,
id: string,
},
}

export interface SessionOccurrence {
id: number,
session_id: number,
start_time: string,
Expand Down
2 changes: 1 addition & 1 deletion utils/dateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function formatTime(dateTimeStr: string) {
return time.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true });
}

export function format12HrQuizSessionTime(time: string): string {
export function format12HrSessionTime(time: string): string {
const isoDate = new Date(time);
const hours = isoDate.getUTCHours();
const minutes = isoDate.getUTCMinutes();
Expand Down

0 comments on commit 2f798e2

Please sign in to comment.