Skip to content

Commit

Permalink
feat(course): implement course editing page #wip
Browse files Browse the repository at this point in the history
  • Loading branch information
danilych committed Feb 11, 2024
1 parent 0a00a96 commit f31eade
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 7 deletions.
6 changes: 4 additions & 2 deletions app/entities/course-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ interface Props {
name: string
price: string
rating: string
isBought?: boolean
isForEdit?: boolean
}

export function CourseCard({ id, picturePath, name, price, rating }: Props) {
export function CourseCard({ id, picturePath, name, price, rating, isBought, isForEdit }: Props) {
return (
<Link to={`/courses/${id}`}>
<Link to={isBought ? `/` : isForEdit ? `/edit-course/${id}` : `/courses/${id}`}>
<div className="w-[484px] relative h-[570px] bg-[#F6F6F6] pt-6 rounded-[20px] px-5">
<img
className="h-[250px] w-[444px] mx-auto rounded-[20px]"
Expand Down
64 changes: 64 additions & 0 deletions app/redux/slices/course.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import instance from '~/axios'

export const createCourse = createAsyncThunk(
'course/createCourse',
async (params: any) => {
const { data } = await instance.post('/Course/Apply', params)

return data
}
)

export const fetchCourse = createAsyncThunk(
'course/fetchCourse',
async (params: any) => {
const { data } = await instance.post('/Course/ViewCourse', params)

return data
}
)

export const updateBlock = createAsyncThunk(
'course/updateBlock',
async (params: any) => {
const { data } = await instance.post('/CourseBlock/Edit', params)

return data
}
)

const initialState = {
course: {
data: null,
isError: false,
status: 'loading',
},
}

const courseSlice = createSlice({
name: 'course',
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(fetchCourse.pending, (state, action) => {
state.course.status = 'loading'

// @ts-ignore
state.course.data = null
})
builder.addCase(fetchCourse.fulfilled, (state, action) => {
state.course.status = 'loaded'
state.course.data = action.payload.data
state.course.isError = action.payload.isError
})
builder.addCase(fetchCourse.rejected, (state, action) => {
state.course.status = 'error'

// @ts-ignore
state.course.data = null
})
},
})

export const courseItemReducer = courseSlice.reducer
2 changes: 2 additions & 0 deletions app/redux/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { configureStore } from "@reduxjs/toolkit";
import { authReducer } from "./slices/auth";
import { courseReducer } from "./slices/courses";
import { userReducer } from "./slices/user";
import { courseItemReducer } from "./slices/course";

const store = configureStore({
reducer: {
courses: courseReducer,
course: courseItemReducer,
auth: authReducer,
user: userReducer,
},
Expand Down
82 changes: 82 additions & 0 deletions app/routes/edit-course.$course.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import type { ThunkDispatch } from '@reduxjs/toolkit'
import { useParams } from '@remix-run/react'
import { Spinner } from 'flowbite-react'
import { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { fetchCourse } from '~/redux/slices/course'
import {
Header2,

Check failure on line 8 in app/routes/edit-course.$course.tsx

View workflow job for this annotation

GitHub Actions / pipeline (21.x)

'Header2' is defined but never used

Check failure on line 8 in app/routes/edit-course.$course.tsx

View workflow job for this annotation

GitHub Actions / pipeline (21.x)

'Header2' is defined but never used
Header3,
Header4,
RoundedInput,
TransparentButton,
} from '~/shared'

export default function Course() {
const params = useParams()

const dispatch = useDispatch<ThunkDispatch<any, any, any>>()

// @ts-ignore
const { course } = useSelector(state => state.course)

const [isPostsLoading, setIsPostLoading] = useState(true)

useEffect(() => {
let formData = new FormData()
formData.append('CourseID', params.course as string)
console.log(params.course)
// formData.append('UserID', window.localStorage.getItem("userId") as string)

dispatch(fetchCourse(formData))
}, [])

Check warning on line 32 in app/routes/edit-course.$course.tsx

View workflow job for this annotation

GitHub Actions / pipeline (21.x)

React Hook useEffect has missing dependencies: 'dispatch' and 'params.course'. Either include them or remove the dependency array

useEffect(() => {

Check warning on line 34 in app/routes/edit-course.$course.tsx

View workflow job for this annotation

GitHub Actions / pipeline (21.x)

React Hook useEffect contains a call to 'setIsPostLoading'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass [course.status] as a second argument to the useEffect Hook
if (course.status === 'loaded') setIsPostLoading(false)

if (course.status === 'loading') setIsPostLoading(true)
})

return (
<div className="w-[1500px] min-h-screen py-12 my-[56px] mx-auto">
{isPostsLoading ? (
<div className="w-full h-screen">
<Spinner
className="absolute top-1/2 left-1/2 mt-[-50px] ml-[-50px]"
aria-label="Extra large spinner example"
size="xl"
/>
</div>
) : (
<div>
<Header3>{course.data.name}</Header3>

<img
className="w-full rounded-[25px] border-2 border-[#454be9] mt-9 h-[534px]"
src={
'https://mystudystorage.blob.core.windows.net/test/' +
course.data.picturePath
}
alt=""
/>

<Header3 className="mt-6">Розділи курсу</Header3>

<div>
<Header4 className="ml-4">Додайти інформаційний блок</Header4>

<div className="mt-2 flex flex-row gap-[26px]">
<RoundedInput placeholder="Назва розділу" className="w-[656px]" />

<div className=" w-[310px]">
<TransparentButton className="text-[#454BE9]">
Додати
</TransparentButton>
</div>
</div>
</div>
</div>
)}
</div>
)
}
5 changes: 1 addition & 4 deletions app/routes/my-account.courses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,11 @@ export default function Courses() {
</div>
) : (
<div className="mt-[42px] w-[1500px] mx-auto grid grid-cols-3 gap-2">

{/* @ts-ignore */}
{courses.items.map((course: any) => (
<CourseCard key={course.id} id={course.id} picturePath={course.picturePath} name={course.name} price={course.price} rating={course.rating} />
))}
{courses.items.map((course: any) => (
<CourseCard key={course.id} id={course.id} picturePath={course.picturePath} name={course.name} price={course.price} rating={course.rating} />
))}
</div>
)}
</div>
Expand Down
1 change: 1 addition & 0 deletions app/routes/my-account.my-courses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export default function MyCourses() {
{/* @ts-ignore */}
{courses.items.map((course: any) => (
<CourseCard
isForEdit={true}
key={course.id}
id={course.id}
picturePath={course.picturePath}
Expand Down
2 changes: 1 addition & 1 deletion app/shared/Inputs/rounded-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const RoundedInput = forwardRef(function RoundedInput({ className, placeh
ref={ref}
placeholder={placeholder}
className={clsx(
'text-[#4E4E51] h-[50px] bg-[#F6F6F6] rounded-[50px] outline-none text-sm font-manrope font-normal w-full border-0',
'text-[#4E4E51] h-[50px] pl-9 bg-[#F6F6F6] rounded-[50px] outline-none text-sm font-manrope font-normal w-full border-0',
className
)}
/>
Expand Down

0 comments on commit f31eade

Please sign in to comment.