get lessons list

This commit is contained in:
Primakov Alexandr Alexandrovich 2024-02-29 09:18:13 +03:00
parent 5134d44e39
commit 80713f7e0f
7 changed files with 72 additions and 54 deletions

View File

@ -16,8 +16,6 @@ module.exports = {
},
},
config: {
"journal.socket.url": "ws://localhost",
"journal.socket.path": "/socket.io/",
"journal.back.url": "/api",
}
}

View File

@ -2,6 +2,7 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { getConfigValue } from "@ijl/cli";
import { keycloak } from "../kc";
import { BaseResponse, Lesson } from "../model";
export const api = createApi({
reducerPath: "auth",
@ -13,7 +14,7 @@ export const api = createApi({
},
}),
endpoints: (builder) => ({
lessonList: builder.query({
lessonList: builder.query<BaseResponse<Lesson[]>, void>({
query: () => '/lesson/list'
})
// signIn: builder.mutation<SignInResponce, SignInRequestBody>({

View File

@ -11,7 +11,7 @@ interface TokenData {
nonce: string;
session_state: string;
acr: string;
'allowed-origins': string[];
"allowed-origins": string[];
realm_access: Realmaccess;
resource_access: Resourceaccess;
scope: string;
@ -25,25 +25,34 @@ interface TokenData {
}
interface Resourceaccess {
'realm-management': Realmaccess;
jurnal: Realmaccess;
broker: Realmaccess;
account: Realmaccess;
'microfrontend-admin': Realmaccess
journal: Realmaccess;
}
interface Realmaccess {
roles: string[];
roles: (string | "teacher")[];
}
export interface UserData extends TokenData {
sub: string;
gravatar: string;
email_verified: boolean;
attributes: Record<string, string[]>
attributes: Record<string, string[]>;
name: string;
preferred_username: string;
given_name: string;
family_name: string;
email: string;
}
export type BaseResponse<Data> = {
success: boolean;
body: Data;
};
export interface Lesson {
_id: string;
name: string;
students: any[];
date: string;
created: string;
}

View File

@ -1,4 +1,5 @@
import { configureStore } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useSelector } from 'react-redux';
import { api } from './api/api';
import { userSlice } from './slices/user';
@ -14,3 +15,5 @@ export const createStore= (preloadedState = {}) => configureStore({
});
export type Store = ReturnType<ReturnType<typeof createStore>['getState']>;
export const useAppSelector: TypedUseSelectorHook<Store> = useSelector;

View File

@ -1,13 +1,15 @@
import React from "react";
import ReactDom from "react-dom";
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from "./app";
import App from './app';
import { keycloak } from "./__data__/kc";
import { createStore } from "./__data__/store";
export default (props) => <App {...props} />;
export const mount = async (Сomponent) => {
let rootElement: ReactDOM.Root
export const mount = async (Сomponent, element = document.getElementById('app')) => {
let user = null;
try {
await keycloak.init({ onLoad: "login-required" }); // 'login-required' });
@ -18,15 +20,16 @@ export const mount = async (Сomponent) => {
}
const store = createStore({ user });
ReactDom.render(<Сomponent store={store} />, document.getElementById("app"));
const rootElement = ReactDOM.createRoot(element);
rootElement.render(<Сomponent store={store} />);
if(module.hot) {
module.hot.accept("./app", () => {
ReactDom.render(<App store={store} />, document.getElementById("app"));
});
module.hot.accept('./app', ()=> {
rootElement.render(<Сomponent store={store} />);
})
}
};
export const unmount = () => {
ReactDom.unmountComponentAtNode(document.getElementById("app"));
rootElement.unmount();
};

View File

@ -16,9 +16,14 @@ import {
import arrow from "../assets/36-arrow-right.svg";
import { keycloak } from "../__data__/kc";
import { useAppSelector } from "../__data__/store";
import { api } from '../__data__/api/api'
import { isTeacher } from "../utils/user";
export const Journal = () => {
const [lessons, setLessons] = useState(null);
const user = useAppSelector((s) => s.user);
const { data, isLoading, error } = api.useLessonListQuery();
useEffect(() => {
const check = async () => {
@ -34,7 +39,7 @@ export const Journal = () => {
console.log("check", data);
} else {
keycloak.onAuthSuccess = check
keycloak.onAuthSuccess = check;
}
};
@ -55,9 +60,9 @@ export const Journal = () => {
const data = await rq.json();
setAnswer(data);
} else {
setAnswer({ message: 'Пользователь не авторизован' })
}
setAnswer({ message: "Пользователь не авторизован" });
}
};
const [value, setValue] = useState("");
const handleChange = useCallback(
@ -81,12 +86,7 @@ export const Journal = () => {
return (
<StartWrapper>
<div>
<IconButton onClick={send} title="Запрос">
<ArrowImg src={arrow} />
</IconButton>
<pre>{JSON.stringify(answer, null, 4)}</pre>
</div>
{isTeacher(user) && (
<form onSubmit={handleSubmit}>
<InputWrapper>
<InputLabel htmlFor="input">Название новой лекции:</InputLabel>
@ -103,14 +103,15 @@ export const Journal = () => {
</IconButton>
</InputWrapper>
</form>
)}
<ul style={{ paddingLeft: 0 }}>
{lessons?.map((lesson) => (
<LessonItem key={lesson.id}>
<Link to={`/journal/l/${lesson.id}`} style={{ display: "flex" }}>
{data?.body?.map((lesson) => (
<LessonItem key={lesson._id}>
<Link to={isTeacher(user) ? `/journal/l/${lesson._id}` : ''} style={{ display: "flex" }}>
<Lessonname>{lesson.name}</Lessonname>
<span>{dayjs(lesson.ts).format("DD MMMM YYYYг.")}</span>
<span>{dayjs(lesson.date).format("DD MMMM YYYYг.")}</span>
<span style={{ marginLeft: "auto" }}>
Участников - {lesson.padavans.length}
Участников - {lesson.students.length}
</span>
</Link>
</LessonItem>

3
src/utils/user.ts Normal file
View File

@ -0,0 +1,3 @@
import { UserData } from "../__data__/model";
export const isTeacher = (user?: UserData): boolean => user?.resource_access?.journal?.roles?.includes('teacher')