Skip to content
Open
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
93 changes: 64 additions & 29 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"mobx-react-lite": "^4.1.0",
"npm": "^10.9.2",
"react": "^19.0.0",
"react-day-picker": "^9.7.0",
"react-day-picker": "^8.10.1",
"react-dom": "^19.0.0",
"react-hook-form": "^7.56.4",
"react-hot-toast": "^2.5.2",
Expand Down
1 change: 0 additions & 1 deletion src/entities/Groups/api/getGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ import { api } from '@/shared/api';

export const getGroups = async (): Promise<Group[]> => {
const { data } = await api.get<Group[]>(`/api/groups/get`, {});

return data;
};
4 changes: 2 additions & 2 deletions src/features/GroupsCRUD/ui/GroupItem/GroupItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const GroupItem = ({
<CardDescription>
Поток: {streamInfo?.streamNumber || 'Неизвестно'} (
{streamInfo?.year || 'N/A'}) • Студентов:{' '}
{group.students.length}
{group.students?.length ?? 0}
{headMan && (
<>
{' '}
Expand Down Expand Up @@ -128,7 +128,7 @@ export const GroupItem = ({
</CollapsibleTrigger>
<CollapsibleContent>
<CardContent>
{group.students.length === 0 ? (
{!group.students || group.students.length === 0 ? (
<div className='text-center py-8 text-muted-foreground'>
<Users className='mx-auto h-12 w-12 mb-4 opacity-50' />
<p>В группе пока нет студентов</p>
Expand Down
2 changes: 1 addition & 1 deletion src/features/GroupsCRUD/ui/GroupsList/GroupsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const GroupsList = () => {
groups.map((group) => {
const streamInfo = getStreamInfo(group.streamId);
const isExpanded = expandedGroups.has(group.id);
const headMan = group.students.find((s) => s.isHeadMan);
const headMan = group.students?.find((s) => s.isHeadMan);

return (
<GroupItem
Expand Down
9 changes: 4 additions & 5 deletions src/features/SemesterCRUD/api/semester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import {
UpdateSemesterDto,
} from '@/features/SemesterCRUD/model';
import { api } from '@/shared/api';
import { BASE_URL_NO_API } from '@/shared/consts/baseUrl';

export const getSemesters = async (isArchive: boolean): Promise<Semester[]> => {
const { data } = await api.get<Semester[]>(`${BASE_URL_NO_API}/semester`, {
const { data } = await api.get<Semester[]>(`/semester`, {
params: {
isArchive,
},
Expand All @@ -19,21 +18,21 @@ export const getSemesters = async (isArchive: boolean): Promise<Semester[]> => {
export const createSemester = async (
payload: CreateSemesterDto,
): Promise<void> => {
await api.post(`${BASE_URL_NO_API}/semester`, payload);
await api.post(`/semester`, payload);
};

export const updateSemester = async (
semesterId: string,
payload: UpdateSemesterDto,
): Promise<void> => {
await api.put(`${BASE_URL_NO_API}/semester/${semesterId}`, payload);
await api.put(`/semester/${semesterId}`, payload);
};

export const deleteOrArchiveSemester = async (
semesterId: string,
isArchive: boolean,
): Promise<void> => {
await api.delete(`${BASE_URL_NO_API}/semester/${semesterId}`, {
await api.delete(`/semester/${semesterId}`, {
params: { isArchive },
});
};
1 change: 0 additions & 1 deletion src/features/SemesterCRUD/ui/SemesterList/SemesterList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
export const SemesterList = () => {
const { mutateAsync: deleteOrArchive } = useDeleteOrArchiveSemester();
const [showArchived, setShowArchived] = useState(false);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { data: semesters = [] } = useSemesters(showArchived);
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [currentSemester, setCurrentSemester] = useState<Semester | null>(null);
Expand Down
2 changes: 1 addition & 1 deletion src/features/StreamsCRUD/model/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface Group {
id: string;
groupNumber: number;
streamId: string;
students: Student[];
students: Student[] | null;
}

export interface StreamSemester {
Expand Down
91 changes: 46 additions & 45 deletions src/shared/ui/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,73 @@
import * as React from 'react';
import { DayPicker } from 'react-day-picker';
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"

import { cn } from '@/shared/lib/utils';
import { buttonVariants } from '@/shared/ui/button';
import { cn } from "@/shared/lib/utils"
import { buttonVariants } from "@/shared/ui/button"

const Calendar = ({
function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: React.ComponentProps<typeof DayPicker>) => {
}: React.ComponentProps<typeof DayPicker>) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn('p-3', className)}
className={cn("p-3", className)}
classNames={{
months: 'flex flex-col sm:flex-row gap-2',
month: 'flex flex-col gap-4',
caption: 'flex justify-center pt-1 relative items-center w-full',
caption_label: 'text-sm font-medium',
nav: 'flex items-center gap-1',
months: "flex flex-col sm:flex-row gap-2",
month: "flex flex-col gap-4",
caption: "flex justify-center pt-1 relative items-center w-full",
caption_label: "text-sm font-medium",
nav: "flex items-center gap-1",
nav_button: cn(
buttonVariants({ variant: 'outline' }),
'size-7 bg-transparent p-0 opacity-50 hover:opacity-100',
buttonVariants({ variant: "outline" }),
"size-7 bg-transparent p-0 opacity-50 hover:opacity-100"
),
nav_button_previous: 'absolute left-1',
nav_button_next: 'absolute right-1',
table: 'w-full border-collapse space-x-1',
head_row: 'flex',
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-x-1",
head_row: "flex",
head_cell:
'text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]',
row: 'flex w-full mt-2',
"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: cn(
'relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-range-end)]:rounded-r-md',
props.mode === 'range'
? '[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md'
: '[&:has([aria-selected])]:rounded-md',
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-range-end)]:rounded-r-md",
props.mode === "range"
? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
: "[&:has([aria-selected])]:rounded-md"
),
day: cn(
buttonVariants({ variant: 'ghost' }),
'size-8 p-0 font-normal aria-selected:opacity-100',
buttonVariants({ variant: "ghost" }),
"size-8 p-0 font-normal aria-selected:opacity-100"
),
day_range_start:
'day-range-start aria-selected:bg-primary aria-selected:text-primary-foreground',
"day-range-start aria-selected:bg-primary aria-selected:text-primary-foreground",
day_range_end:
'day-range-end aria-selected:bg-primary aria-selected:text-primary-foreground',
"day-range-end aria-selected:bg-primary aria-selected:text-primary-foreground",
day_selected:
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
day_today: 'bg-accent text-accent-foreground',
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
day_today: "bg-accent text-accent-foreground",
day_outside:
'day-outside text-muted-foreground aria-selected:text-muted-foreground',
day_disabled: 'text-muted-foreground opacity-50',
"day-outside text-muted-foreground aria-selected:text-muted-foreground",
day_disabled: "text-muted-foreground opacity-50",
day_range_middle:
'aria-selected:bg-accent aria-selected:text-accent-foreground',
day_hidden: 'invisible',
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
...classNames,
}}
// components={{
// IconLeft: ({ className, ...props }) => (
// <ChevronLeft className={cn('size-4', className)} {...props} />
// ),
// IconRight: ({ className, ...props }) => (
// <ChevronRight className={cn('size-4', className)} {...props} />
// ),
// }}
components={{
IconLeft: ({ className, ...props }) => (
<ChevronLeft className={cn("size-4", className)} {...props} />
),
IconRight: ({ className, ...props }) => (
<ChevronRight className={cn("size-4", className)} {...props} />
),
}}
{...props}
/>
);
};
)
}

export { Calendar };
export { Calendar }
4 changes: 1 addition & 3 deletions src/shared/ui/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ function PopoverContent({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
return (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
<PopoverPrimitive.Content
data-slot="popover-content"
align={align}
sideOffset={sideOffset}
Expand All @@ -33,7 +32,6 @@ function PopoverContent({
)}
{...props}
/>
</PopoverPrimitive.Portal>
)
}

Expand Down