group drop down list

This commit is contained in:
Виталий Лавшонок
2025-12-10 02:37:16 +03:00
parent 47152a921e
commit c761f337b1
2 changed files with 122 additions and 36 deletions

View File

@@ -21,6 +21,7 @@ import {
import { NumberInput } from '../components/input/NumberInput'; import { NumberInput } from '../components/input/NumberInput';
import { cn } from '../lib/cn'; import { cn } from '../lib/cn';
import DateInput from '../components/input/DateInput'; import DateInput from '../components/input/DateInput';
import { fetchMyGroups } from '../redux/slices/groups';
interface Mission { interface Mission {
id: number; id: number;
@@ -92,7 +93,7 @@ const ContestEditor = () => {
missionIds: [], missionIds: [],
articleIds: [], articleIds: [],
}); });
const myname = useAppSelector((state) => state.auth.username);
const [missions, setMissions] = useState<Mission[]>([]); const [missions, setMissions] = useState<Mission[]>([]);
const statusDelete = useAppSelector( const statusDelete = useAppSelector(
@@ -106,6 +107,16 @@ const ContestEditor = () => {
(state) => state.contests.fetchContestById, (state) => state.contests.fetchContestById,
); );
const myGroups = useAppSelector(
(state) => state.groups.fetchMyGroups.groups,
).filter((group) =>
group.members.some(
(member) =>
member.username === myname &&
member.role.includes('Administrator'),
),
);
function toLocalInputValue(utcString: string) { function toLocalInputValue(utcString: string) {
const d = new Date(utcString); const d = new Date(utcString);
@@ -193,6 +204,7 @@ const ContestEditor = () => {
useEffect(() => { useEffect(() => {
if (refactor && contestByIdstatus == 'successful' && contestById) { if (refactor && contestByIdstatus == 'successful' && contestById) {
dispatch(fetchMyGroups());
setContest({ setContest({
...contestById, ...contestById,
// groupIds: contestById.groups.map(group => group.groupId), // groupIds: contestById.groups.map(group => group.groupId),
@@ -205,8 +217,6 @@ const ContestEditor = () => {
} }
}, [contestById]); }, [contestById]);
console.log(contest);
const visibilityDefaultState = const visibilityDefaultState =
visibilityItems.find( visibilityItems.find(
(i) => contest && i.value === contest.visibility, (i) => contest && i.value === contest.visibility,
@@ -217,6 +227,17 @@ const ContestEditor = () => {
(i) => contest && i.value === contest.scheduleType, (i) => contest && i.value === contest.scheduleType,
) ?? scheduleTypeItems[0]; ) ?? scheduleTypeItems[0];
const groupItems = myGroups.map((v) => {
return {
value: '' + v.id,
text: v.name,
};
});
const groupIdDefaultState =
myGroups.find((g) => g.id == contest?.groupId) ??
myGroups[0] ??
undefined;
return ( return (
<div className="h-screen grid grid-rows-[60px,1fr] text-liquid-white"> <div className="h-screen grid grid-rows-[60px,1fr] text-liquid-white">
<Header backClick={() => navigate(back || '/home/contests')} /> <Header backClick={() => navigate(back || '/home/contests')} />
@@ -287,29 +308,50 @@ const ContestEditor = () => {
<div <div
className={cn( className={cn(
' grid grid-flow-row grid-rows-[0fr] opacity-0 transition-all duration-200', ' grid grid-flow-row grid-rows-[0fr] opacity-0 transition-all duration-200 mb-[10px]',
contest.visibility == 'GroupPrivate' && contest.visibility == 'GroupPrivate' &&
'grid-rows-[1fr] opacity-100', 'grid-rows-[1fr] opacity-100',
)} )}
> >
<div className="overflow-hidden"> {groupIdDefaultState ? (
<div className="grid grid-cols-2 gap-[10px] mt-[10px]"> <div
<NumberInput className={cn(
defaultState={contest.groupId ?? 1} contest.visibility !=
name="groupId" 'GroupPrivate' &&
label="Id группы" 'overflow-hidden',
placeholder="Например: 3" )}
minValue={1} >
maxValue={1000000000000000} <div>
onChange={(v) => <label className="block text-sm mb-2 mt-[10px]">
handleChange( Группа для привязки
'groupId', </label>
Number(v),
) <DropDownList
} items={groupItems}
/> defaultState={{
value:
'' +
groupIdDefaultState.id,
text: groupIdDefaultState.name,
}}
onChange={(v) => {
handleChange(
'groupId',
Number(v),
);
}}
weight="w-full"
/>
</div>
</div> </div>
</div> ) : (
<div className="overflow-hidden">
<div className="text-liquid-red my-[20px]">
У вас нет группы вкоторой вы
являетесь Администратором!
</div>
</div>
)}
</div> </div>
{/* Даты */} {/* Даты */}

View File

@@ -17,6 +17,7 @@ import {
} from '../../../components/input/DropDownList'; } from '../../../components/input/DropDownList';
import DateInput from '../../../components/input/DateInput'; import DateInput from '../../../components/input/DateInput';
import { cn } from '../../../lib/cn'; import { cn } from '../../../lib/cn';
import { fetchMyGroups } from '../../../redux/slices/groups';
function toUtc(localDateTime?: string): string { function toUtc(localDateTime?: string): string {
if (!localDateTime) return ''; if (!localDateTime) return '';
@@ -80,6 +81,16 @@ const ModalCreateContest: FC<ModalCreateContestProps> = ({
const contest = useAppSelector( const contest = useAppSelector(
(state) => state.contests.createContest.contest, (state) => state.contests.createContest.contest,
); );
const myname = useAppSelector((state) => state.auth.username);
const myGroups = useAppSelector(
(state) => state.groups.fetchMyGroups.groups,
).filter((group) =>
group.members.some(
(member) =>
member.username === myname &&
member.role.includes('Administrator'),
),
);
useEffect(() => { useEffect(() => {
if (status === 'successful') { if (status === 'successful') {
@@ -92,6 +103,12 @@ const ModalCreateContest: FC<ModalCreateContestProps> = ({
} }
}, [status]); }, [status]);
useEffect(() => {
if (active) {
dispatch(fetchMyGroups());
}
}, [active]);
const handleChange = (key: keyof CreateContestBody, value: any) => { const handleChange = (key: keyof CreateContestBody, value: any) => {
setForm((prev) => ({ ...prev, [key]: value })); setForm((prev) => ({ ...prev, [key]: value }));
}; };
@@ -105,7 +122,16 @@ const ModalCreateContest: FC<ModalCreateContestProps> = ({
}), }),
); );
}; };
const groupItems = myGroups.map((v) => {
return {
value: '' + v.id,
text: v.name,
};
});
const groupIdDefaultState =
myGroups.find((g) => g.id == form?.groupId) ?? myGroups[0] ?? undefined;
console.log(groupItems, myGroups, groupIdDefaultState);
return ( return (
<Modal <Modal
className="bg-liquid-background border-liquid-lighter border-[2px] p-[25px] rounded-[20px] text-liquid-white" className="bg-liquid-background border-liquid-lighter border-[2px] p-[25px] rounded-[20px] text-liquid-white"
@@ -165,26 +191,44 @@ const ModalCreateContest: FC<ModalCreateContestProps> = ({
<div <div
className={cn( className={cn(
' grid grid-flow-row grid-rows-[0fr] opacity-0 transition-all duration-200', ' grid grid-flow-row grid-rows-[0fr] opacity-0 transition-all duration-200 mb-[10px]',
form.visibility == 'GroupPrivate' && form.visibility == 'GroupPrivate' &&
'grid-rows-[1fr] opacity-100', 'grid-rows-[1fr] opacity-100',
)} )}
> >
<div className="overflow-hidden"> {groupIdDefaultState ? (
<div className="grid grid-cols-2 gap-[10px] mt-[10px]"> <div
<NumberInput className={cn(
defaultState={form.groupId ?? 1} form.visibility != 'GroupPrivate' &&
name="groupId" 'overflow-hidden',
label="Id группы" )}
placeholder="Например: 3" >
minValue={1} <div>
maxValue={1000000000000000} <label className="block text-sm mb-2 mt-[10px]">
onChange={(v) => Группа для привязки
handleChange('groupId', Number(v)) </label>
}
/> <DropDownList
items={groupItems}
defaultState={{
value: '' + groupIdDefaultState.id,
text: groupIdDefaultState.name,
}}
onChange={(v) => {
handleChange('groupId', Number(v));
}}
weight="w-full"
/>
</div>
</div> </div>
</div> ) : (
<div className="overflow-hidden">
<div className="text-liquid-red my-[20px]">
У вас нет группы вкоторой вы являетесь
Администратором!
</div>
</div>
)}
</div> </div>
{/* Даты */} {/* Даты */}