11import React , { useEffect , useState } from 'react' ;
22import Cookies from 'js-cookie' ;
33import Notiflix from 'notiflix' ;
4- import { Modal } from '../Modal.js' ;
4+ import { Modal } from '../Modal.js' ;
5+ import SearchBar from '../search-bar.js'
56
67export function CourseDashboard ( ) {
78 const [ courseInfo , setCourseInfo ] = useState ( null ) ;
@@ -10,17 +11,23 @@ export function CourseDashboard() {
1011 title : "" ,
1112 description : "" ,
1213 } ) ;
13- const [ error , setError ] = useState ( null ) ;
14+ const [ searchQuery , setSearchQuery ] = useState ( "" ) ;
15+ const [ error , setError ] = useState ( null ) ;
16+ const [ isModalActive , setIsModalActive ] = useState ( false ) ;
1417
1518 const handleChange = ( e ) => {
1619 const { name, value } = e . target ;
1720 setNewCourse ( { ...newCourse , [ name ] : value } ) ;
1821 } ;
1922
20- const handleCreateCourse = async ( e ) => {
21- if ( newCourse . title === "" || newCourse . description === "" ) {
22- return
23- }
23+ const handleSearchChange = ( e ) => {
24+ setSearchQuery ( e . target . value ) ;
25+ } ;
26+
27+ const handleCreateCourse = async ( ) => {
28+ if ( newCourse . title === "" || newCourse . description === "" ) {
29+ return ;
30+ }
2431
2532 const userId = Cookies . get ( 'userId' ) ;
2633 try {
@@ -31,7 +38,7 @@ export function CourseDashboard() {
3138 } ,
3239 body : JSON . stringify ( {
3340 title : newCourse . title ,
34- description : newCourse . description
41+ description : newCourse . description ,
3542 } ) ,
3643 } ) ;
3744
@@ -59,26 +66,26 @@ export function CourseDashboard() {
5966
6067 async function fetchCourses ( ) {
6168 await fetch ( `http://localhost:4000/courses/${ userId } ` )
62- . then ( ( response ) => {
63- if ( ! response . ok ) {
64- throw new Error ( 'Network response was not ok' ) ;
65- }
66- return response . json ( ) ;
67- } )
68- . then ( ( data ) => setCourseInfo ( data . courses ) )
69- . catch ( ( error ) => setError ( error . message ) ) ;
69+ . then ( ( response ) => {
70+ if ( ! response . ok ) {
71+ throw new Error ( 'Network response was not ok' ) ;
72+ }
73+ return response . json ( ) ;
74+ } )
75+ . then ( ( data ) => setCourseInfo ( data . courses ) )
76+ . catch ( ( error ) => setError ( error . message ) ) ;
7077 }
7178
7279 async function fetchUser ( ) {
7380 await fetch ( `http://localhost:4000/user/${ userId } ` )
74- . then ( ( response ) => {
75- if ( ! response . ok ) {
76- throw new Error ( 'Network response was not ok' ) ;
77- }
78- return response . json ( ) ;
79- } )
80- . then ( ( data ) => setUserInfo ( data . user ) )
81- . catch ( ( error ) => setError ( error . message ) ) ;
81+ . then ( ( response ) => {
82+ if ( ! response . ok ) {
83+ throw new Error ( 'Network response was not ok' ) ;
84+ }
85+ return response . json ( ) ;
86+ } )
87+ . then ( ( data ) => setUserInfo ( data . user ) )
88+ . catch ( ( error ) => setError ( error . message ) ) ;
8289 }
8390
8491 fetchCourses ( ) ;
@@ -89,41 +96,53 @@ export function CourseDashboard() {
8996 if ( ! courseInfo || ! userInfo ) return < p > Loading...</ p > ;
9097
9198 let createButton = null ;
92- if ( userInfo . role === "educator" ) {
93- createButton = < Modal
94- title = { "Create New Course" }
95- trigger = {
96- < div className = "bg-blue-500 p-2 rounded shadow hover:bg-blue-700 m-auto text-center text-sm text-white font-semibold hover:cursor-pointer" >
97- < div > + New Course</ div >
98- </ div >
99- }
100- inputFields = { {
101- title : "Course Name" ,
102- description : "Course Description"
103- } }
104- changeHandler = { handleChange }
105- confirmHandler = { handleCreateCourse }
106- />
99+ if ( userInfo . role === "educator" ) {
100+ createButton = (
101+ < Modal
102+ title = { "Create New Course" }
103+ trigger = {
104+ < div className = "bg-blue-500 p-3 rounded shadow hover:bg-blue-700 m-auto text-center text-sm text-white font-semibold hover:cursor-pointer" >
105+ < div > + New Course</ div >
106+ </ div >
107+ }
108+ inputFields = { {
109+ title : "Course Name" ,
110+ description : "Course Description" ,
111+ } }
112+ changeHandler = { handleChange }
113+ confirmHandler = { async ( ) => {
114+ await handleCreateCourse ( ) ;
115+ setIsModalActive ( false ) ;
116+ } }
117+ onToggle = { setIsModalActive }
118+ />
119+
120+ ) ;
107121 }
108122
109- var courseList = [ ] ;
110- //Push all courses into courseList
111- courseInfo . forEach ( course => {
112- courseList . push (
113- < a href = { `/courses/ ${ course . ID } ` } >
114- < div className = "bg-gray-100 p-4 rounded shadow hover:bg-gray-300" >
115- < h3 className = "text-xl font-semibold truncate overflow-hidden" > { course . title } </ h3 >
116- < p className = "mt-2 " > { course . description } </ p >
117- </ div >
118- </ a >
119- )
120- } ) ;
121-
123+ const filteredCourses = courseInfo . filter ( ( course ) =>
124+ course . title . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) )
125+ ) ;
126+
127+ const courseList = filteredCourses . map ( ( course ) => (
128+ < a href = { `/courses/ ${ course . ID } ` } key = { course . ID } >
129+ < div className = "bg-gray-100 p-4 rounded shadow hover:bg-gray-300" >
130+ < h3 className = "text-xl font-semibold truncate overflow-hidden " > { course . title } </ h3 >
131+ < p className = "mt-2" > { course . description } </ p >
132+ </ div >
133+ </ a >
134+ ) ) ;
135+
122136 return (
123137 < div className = "p-6" >
124- < div className = "flex justify-between flex-wrap mb-5" >
138+ < div className = "mb-5" >
125139 < h1 className = "text-2xl font-bold" > Courses</ h1 >
126- { createButton }
140+ </ div >
141+ < div className = "mb-5" >
142+ < div className = "flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4" >
143+ { createButton }
144+ < SearchBar onChange = { handleSearchChange } disabled = { isModalActive } />
145+ </ div >
127146 </ div >
128147 < div className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6" >
129148 { courseList }
0 commit comments