add ability to show QR code

This commit is contained in:
Majd_dk 2024-11-09 14:17:31 +03:00
parent d04423db0f
commit c6c0958a3f
8 changed files with 141 additions and 1 deletions

50
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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}>

View 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;

View 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;

View File

@ -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>
); );
}; };

View File

@ -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)}
/> />
); );
}, },

View File

@ -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