Merge branch 'dev' of https://git.point-dev.net/Karimaldeen/Quiz_dashboard into dev
This commit is contained in:
commit
34d6d3affd
50
package-lock.json
generated
50
package-lock.json
generated
|
|
@ -27,6 +27,7 @@
|
||||||
"mathjs": "^13.1.1",
|
"mathjs": "^13.1.1",
|
||||||
"mathml-to-latex": "^1.4.1",
|
"mathml-to-latex": "^1.4.1",
|
||||||
"npm": "^10.8.3",
|
"npm": "^10.8.3",
|
||||||
|
"qrcode.react": "^4.1.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
|
@ -34,6 +35,7 @@
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-katex": "^3.0.1",
|
"react-katex": "^3.0.1",
|
||||||
"react-leaflet": "^4.2.1",
|
"react-leaflet": "^4.2.1",
|
||||||
|
"react-qr-code": "^2.0.15",
|
||||||
"react-query": "^3.39.3",
|
"react-query": "^3.39.3",
|
||||||
"react-router-dom": "^6.26.2",
|
"react-router-dom": "^6.26.2",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
|
|
@ -12015,6 +12017,21 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/qr.js": {
|
||||||
|
"version": "0.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
|
||||||
|
"integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/qrcode.react": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-uqXVIIVD/IPgWLYxbOczCNAQw80XCM/LulYDADF+g2xDsPj5OoRwSWtIS4jGyp295wyjKstfG1qIv/I2/rNWpQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/querystringify": {
|
"node_modules/querystringify": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
|
|
@ -12761,6 +12778,19 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-qr-code": {
|
||||||
|
"version": "2.0.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.15.tgz",
|
||||||
|
"integrity": "sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
|
"qr.js": "0.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-query": {
|
"node_modules/react-query": {
|
||||||
"version": "3.39.3",
|
"version": "3.39.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
|
||||||
|
|
@ -23463,6 +23493,17 @@
|
||||||
"integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
|
"integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"qr.js": {
|
||||||
|
"version": "0.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
|
||||||
|
"integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ=="
|
||||||
|
},
|
||||||
|
"qrcode.react": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-uqXVIIVD/IPgWLYxbOczCNAQw80XCM/LulYDADF+g2xDsPj5OoRwSWtIS4jGyp295wyjKstfG1qIv/I2/rNWpQ==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"querystringify": {
|
"querystringify": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
|
|
@ -23980,6 +24021,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-qr-code": {
|
||||||
|
"version": "2.0.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.15.tgz",
|
||||||
|
"integrity": "sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==",
|
||||||
|
"requires": {
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
|
"qr.js": "0.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-query": {
|
"react-query": {
|
||||||
"version": "3.39.3",
|
"version": "3.39.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
"mathjs": "^13.1.1",
|
"mathjs": "^13.1.1",
|
||||||
"mathml-to-latex": "^1.4.1",
|
"mathml-to-latex": "^1.4.1",
|
||||||
"npm": "^10.8.3",
|
"npm": "^10.8.3",
|
||||||
|
"qrcode.react": "^4.1.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
|
@ -29,6 +30,7 @@
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-katex": "^3.0.1",
|
"react-katex": "^3.0.1",
|
||||||
"react-leaflet": "^4.2.1",
|
"react-leaflet": "^4.2.1",
|
||||||
|
"react-qr-code": "^2.0.15",
|
||||||
"react-query": "^3.39.3",
|
"react-query": "^3.39.3",
|
||||||
"react-router-dom": "^6.26.2",
|
"react-router-dom": "^6.26.2",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import { RiDeleteBin6Fill } from "react-icons/ri";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { BsEyeFill } from "react-icons/bs";
|
import { BsEyeFill } from "react-icons/bs";
|
||||||
import { GoTrash } from "react-icons/go";
|
import { GoTrash } from "react-icons/go";
|
||||||
|
import { BsQrCode } from "react-icons/bs";
|
||||||
|
|
||||||
|
|
||||||
interface ActionButtonsProps {
|
interface ActionButtonsProps {
|
||||||
canEdit?: boolean;
|
canEdit?: boolean;
|
||||||
|
|
@ -17,9 +19,13 @@ interface ActionButtonsProps {
|
||||||
onShow?: () => void;
|
onShow?: () => void;
|
||||||
index?: number;
|
index?: number;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
canShowQr?:boolean
|
||||||
|
onShoqQr?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActionButtons: React.FC<ActionButtonsProps> = ({
|
const ActionButtons: React.FC<ActionButtonsProps> = ({
|
||||||
|
canShowQr,
|
||||||
|
onShoqQr,
|
||||||
canEdit,
|
canEdit,
|
||||||
canDelete,
|
canDelete,
|
||||||
editTooltipTitle = "practical.edit",
|
editTooltipTitle = "practical.edit",
|
||||||
|
|
@ -38,6 +44,10 @@ const ActionButtons: React.FC<ActionButtonsProps> = ({
|
||||||
: "buttonAction";
|
: "buttonAction";
|
||||||
return (
|
return (
|
||||||
<Space size="middle" className={`${CustomClassName} ${className} `}>
|
<Space size="middle" className={`${CustomClassName} ${className} `}>
|
||||||
|
{canShowQr && (
|
||||||
|
<BsQrCode onClick={onShoqQr} size={22} style={{ color: "#A098AE" }} />
|
||||||
|
)}
|
||||||
|
|
||||||
{canEdit && (
|
{canEdit && (
|
||||||
<Tooltip placement="top" title={t(editTooltipTitle)} color="#E0E0E0">
|
<Tooltip placement="top" title={t(editTooltipTitle)} color="#E0E0E0">
|
||||||
<span onClick={onEdit}>
|
<span onClick={onEdit}>
|
||||||
|
|
@ -54,7 +64,7 @@ const ActionButtons: React.FC<ActionButtonsProps> = ({
|
||||||
{canShow && (
|
{canShow && (
|
||||||
<BsEyeFill onClick={onShow} size={22} style={{ color: "green" }} />
|
<BsEyeFill onClick={onShow} size={22} style={{ color: "green" }} />
|
||||||
)}
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
15
src/Components/Table/QRCodeGenerator.tsx
Normal file
15
src/Components/Table/QRCodeGenerator.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React from 'react';
|
||||||
|
import QRCode from 'react-qr-code';
|
||||||
|
|
||||||
|
|
||||||
|
const QRCodeGenerator = ({url,serial}:any) => {
|
||||||
|
const qrValue = `${url}/${serial}`
|
||||||
|
console.log(qrValue)
|
||||||
|
return (
|
||||||
|
<div style={{display:'flex',justifyContent:'center'}} >
|
||||||
|
<QRCode value={qrValue} size={230} type='link' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QRCodeGenerator;
|
||||||
52
src/Layout/Dashboard/QrCodeModels.tsx
Normal file
52
src/Layout/Dashboard/QrCodeModels.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Modal } from "antd";
|
||||||
|
import { useModalState } from "../../zustand/Modal";
|
||||||
|
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { MdCancel } from "react-icons/md";
|
||||||
|
import QRCodeGenerator from "../../Components/Table/QRCodeGenerator";
|
||||||
|
|
||||||
|
interface ModalFormProps {
|
||||||
|
ModelEnum: any;
|
||||||
|
isNavigate?: boolean;
|
||||||
|
idVerify?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QrCodeModels: React.FC<ModalFormProps> = ({
|
||||||
|
ModelEnum,
|
||||||
|
isNavigate = false,
|
||||||
|
idVerify = true,
|
||||||
|
}) => {
|
||||||
|
const { isOpen, setIsOpen } = useModalState((state) => state);
|
||||||
|
|
||||||
|
const { objectToEdit, setObjectToEdit } = useObjectToEdit();
|
||||||
|
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
setIsOpen("");
|
||||||
|
setObjectToEdit({});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
className="ModalForm"
|
||||||
|
centered
|
||||||
|
width={"300px"}
|
||||||
|
footer={false}
|
||||||
|
open={isOpen === ModelEnum}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
>
|
||||||
|
<header dir="ltr">
|
||||||
|
<MdCancel onClick={handleCancel} />
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main className="main_modal">
|
||||||
|
<div className="ValidationField w-100 mb-5 ">
|
||||||
|
<QRCodeGenerator url = {`https://nerd-back.point-dev.net/api/students/question`} serial={objectToEdit.serial}/>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QrCodeModels;
|
||||||
|
|
@ -17,6 +17,7 @@ import { canAddQuestion } from "../../../utils/hasAbilityFn";
|
||||||
import FilterLayout from "../../../Layout/Dashboard/FilterLayout";
|
import FilterLayout from "../../../Layout/Dashboard/FilterLayout";
|
||||||
import FilterForm from "./FilterForm";
|
import FilterForm from "./FilterForm";
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||||
|
import QrCodeModels from "../../../Layout/Dashboard/QrCodeModels";
|
||||||
const Table = lazy(() => import("./Table"));
|
const Table = lazy(() => import("./Table"));
|
||||||
|
|
||||||
const TableHeader = () => {
|
const TableHeader = () => {
|
||||||
|
|
@ -82,6 +83,9 @@ const TableHeader = () => {
|
||||||
deleteMutation={deleteMutation}
|
deleteMutation={deleteMutation}
|
||||||
ModelEnum={ModalEnum?.QUESTION_DELETE}
|
ModelEnum={ModalEnum?.QUESTION_DELETE}
|
||||||
/>
|
/>
|
||||||
|
<QrCodeModels
|
||||||
|
ModelEnum={ModalEnum?.QUESTION_QR}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,10 @@ export const useColumns = () => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
navigate(`${ABILITIES_ENUM?.QUESTION}/${record?.id}`);
|
navigate(`${ABILITIES_ENUM?.QUESTION}/${record?.id}`);
|
||||||
};
|
};
|
||||||
|
const handleClickQr = (data:any)=>{
|
||||||
|
setObjectToEdit(data);
|
||||||
|
setIsOpen(ModalEnum?.QUESTION_QR);
|
||||||
|
}
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
const columns: TableColumnsType<Question> = [
|
const columns: TableColumnsType<Question> = [
|
||||||
|
|
@ -113,6 +117,8 @@ export const useColumns = () => {
|
||||||
index={index}
|
index={index}
|
||||||
onDelete={() => handelDelete(record)}
|
onDelete={() => handelDelete(record)}
|
||||||
onEdit={() => handleEdit(record)}
|
onEdit={() => handleEdit(record)}
|
||||||
|
canShowQr={true}
|
||||||
|
onShoqQr={() =>handleClickQr(record)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ export enum ModalEnum {
|
||||||
|
|
||||||
///// Question
|
///// Question
|
||||||
QUESTION_DELETE = "Question.delete",
|
QUESTION_DELETE = "Question.delete",
|
||||||
|
QUESTION_QR = "Question.QrCode",
|
||||||
QUESTION_ACCEPT = "Question.ACCEPT",
|
QUESTION_ACCEPT = "Question.ACCEPT",
|
||||||
|
|
||||||
///Grade
|
///Grade
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user