Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add edit bar for #46

Merged
merged 1 commit into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/pages/Course/Lesson/LessonWorks/LessonWorks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import type { Subscription } from 'rxjs';
import { homeworkService } from 'services';
import { formatI18nT } from 'shared';

import EditBar from 'ui/EditBar/EditBar';

import LessonReview from './LessonReview/LessonReview';
import LessonWork from './LessonWork/LessonWork';
import WorkCard from './WorkCard/WorkCard';
Expand Down Expand Up @@ -35,6 +37,7 @@ function mapStateToProps(state: IRootState): IProps {
function LessonWorks({ authedUserId }: IProps) {
const { courseId, lessonId } = useParams() as { courseId: string, lessonId: string };
const { filter, patchFilter } = useFilter();
const [source, setSource] = useState<'remote' | 'local'>('remote');

const [homeworks, setHomeworks] = useState<IHomeworkDataWPopulate[] | undefined>(undefined);
const [homeworksState, setHomeworksState] = useState<THomeworkStateState>({ type: 'idle' });
Expand Down Expand Up @@ -63,6 +66,7 @@ function LessonWorks({ authedUserId }: IProps) {
homeworkService.getHomeworkBS({
filter: { courseId, lessonId },
populate: { user: true },
reviewSource: source,
}).then(bs => {
subscription = bs.subscribe(e => {
if (e && !(e instanceof Error)) {
Expand All @@ -78,7 +82,7 @@ function LessonWorks({ authedUserId }: IProps) {
});

return () => subscription?.unsubscribe();
}, [courseId, lessonId]);
}, [courseId, lessonId, source]);

const selectedHomework = useMemo(() => {
return homeworks?.find(data => data.homework.userId === filter.userId);
Expand All @@ -93,6 +97,12 @@ function LessonWorks({ authedUserId }: IProps) {
<Fragment>
<LessonWork homework={selectedHomework}/>
<LessonReview homework={selectedHomework}/>
<EditBar
source={source}
handleSourceChange={setSource}
handleUpload={() => console.log('upload')}
handleDownload={() => console.log('download')}
/>
</Fragment>);
}

Expand Down
8 changes: 4 additions & 4 deletions src/pages/Course/Lesson/LessonWorks/WorkCard/WorkCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Link from 'ui/Link/Link';

import classes from './WorkCard.module.scss';

import { URLSections, type IHomeworkDataWPopulate } from 'types';
import { URLSections, type IHomeworkDataWPopulate, IHomeworkImageData } from 'types';

const cx = classNames.bind(classes);

Expand All @@ -20,7 +20,7 @@ interface IProps {
function WorkCard({ homework }: IProps) {
const { courseId, lessonId } = useParams() as { courseId: string, lessonId: string };
const user = homework.populate?.user;
const coverImage = homework.homework.images[0];
const coverImage = homework.homework.images[0] as IHomeworkImageData | undefined;

return (
<div className={cx({ _: true, hidden: false })}>
Expand All @@ -30,8 +30,8 @@ function WorkCard({ homework }: IProps) {
to={URLSections.Course.Lesson.Results.to({ courseId, lessonId, params: { userId: user?.id }})}
>
<Img
src={coverImage.src}
alt={coverImage.alt}
src={coverImage?.src ?? ''}
alt={coverImage?.alt ?? ''}
/>
<div className={classes.overlay}/>
</Link>
Expand Down
36 changes: 35 additions & 1 deletion src/services/homework.service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class HomeworkService {
public async getHomeworkBS(props: {
filter: { courseId: string, lessonId?: string, userId?: string, id?: string }
populate?: { user?: boolean }
reviewSource?: 'local' | 'remote'
}) {
try {
type TAction = null | { homeworks: IHomeworkDataWPopulate[] } | Error;
Expand Down Expand Up @@ -118,6 +119,7 @@ class HomeworkService {
private async _fetch(props: {
filter: { courseId: string, lessonId?: string, userId?: string, id?: string }
populate?: { user?: boolean }
reviewSource?: 'local' | 'remote'
}) {
try {
const homeworksData = await dataService.homework.getAll(props.filter);
Expand All @@ -143,8 +145,20 @@ class HomeworkService {
}
}

// add local review if needed
let reviewMap: Map<string, IHomeworkData['review']>;
if (props.reviewSource === 'local') {
reviewMap = new Map();
for (const homework of homeworksData) {
reviewMap.set(homework.id, getReview({ homeworkId: homework.id }));
}
}

const homeworks: IHomeworkDataWPopulate[] = homeworksData.map(homework => ({
homework,
homework: {
...homework,
...reviewMap && reviewMap.has(homework.id) && { review: reviewMap.get(homework.id) },
},
...populateMap && { populate: populateMap.get(homework.id) },
}));

Expand All @@ -160,3 +174,23 @@ class HomeworkService {
}

export const homeworkService = new HomeworkService();

type TReview = {
homeworkId: string
review: IHomeworkData['review']
}

const review1: TReview = {
homeworkId: 'how-to-draw_SpotPractice_kfKAEY_hw-3C8wwg4FdjebKe1FunCdlPs4M533',
review: [
{ type: 'text', text: 'Это моё первая обратная связь' },
],
};

const allReviews = [
review1
];

function getReview(filter: { homeworkId: string }) {
return allReviews.find(({ homeworkId }) => homeworkId === filter.homeworkId)?.review;
}
53 changes: 53 additions & 0 deletions src/ui/EditBar/EditBar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@import 'styles/index';

._ {
position: absolute;
top: 0;
right: set-calc($padding-x-desk-page);
height: 100vh;
}

.stickyBtnStaff {
display: flex;
align-items: flex-end;
flex-direction: column;
justify-content: flex-end;
opacity: 1;

position: absolute;
top: 80%;
min-height: calc(var(--page-height, 100vh) - 76vh);
width: 0;
z-index: 9999;
}

.stickyBtnShaftInner {
position: sticky;
bottom: set-calc(24);
right: 0;

align-items: flex-start;
display: flex;
justify-content: flex-end;
}

.stickyBtn {
background: hsl(107,94%,35%);
height: set-calc(48);
padding: set-calc(8) set-calc(24);
bottom: set-calc(8);
color: $white;
border-radius: set-calc(8);
cursor: pointer;
display: inline-block;
text-decoration: none;
white-space: nowrap;
}

.stickyBtn:hover {
background: hsl(107,94%,29%);
}

.stickyBtn:not(:last-child) {
margin-right: set-calc(4);
}
39 changes: 39 additions & 0 deletions src/ui/EditBar/EditBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createPortal } from 'react-dom';

import classes from './EditBar.module.scss';

interface IProps {
source: 'remote' | 'local'
handleSourceChange: (source: 'remote' | 'local') => void
handleUpload: () => void
handleDownload: () => void
}
export default function EditBar(props: Readonly<IProps>) {
const { source, handleSourceChange } = props;
return createPortal((
<section className={classes._}>
<div className={classes.stickyBtnStaff}>
<div className={classes.stickyBtnShaftInner}>
<div
className={classes.stickyBtn + ' s-text-24'}
onClick={props.handleUpload}
>
Upload
</div>
<div
className={classes.stickyBtn + ' s-text-24'}
onClick={props.handleDownload}
>
Download
</div>
<div
className={classes.stickyBtn + ' s-text-24'}
onClick={() => handleSourceChange(source === 'local' ? 'remote' : 'local')}
>
{`use ${source === 'local' ? 'remote' : 'local'}`}
</div>
</div>
</div>
</section>
), document.body);
}
Loading