Skip to content

Commit

Permalink
fix tickets-crud that was introduced in issues 242
Browse files Browse the repository at this point in the history
-Admins and Coordinators will be able to create tickets
-Traineess will be able to see tickets assigned to them
-Also Admins and Admins can also perform CRUD operations on Tickets
  • Loading branch information
amiparadis250 committed Sep 17, 2024
1 parent 07b4e1f commit 40370c5
Show file tree
Hide file tree
Showing 99 changed files with 2,005 additions and 1,021 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"no-shadow": 0,
"no-unused-expressions": 0,
"react/require-default-props": 0,
"import/prefer-default-export": 0
"import/prefer-default-export": 0,
"react/no-unstable-nested-components": 0
}
}
12 changes: 8 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
rel="stylesheet"
/> -->

<link href="https://fonts.googleapis.com/css2?family=PT+Serif:wght@400;700&display=swap" rel="stylesheet">

<link
href="https://fonts.googleapis.com/css2?family=PT+Serif:wght@400;700&display=swap"
rel="stylesheet"
/>
</head>
<body class="dark:bg-dark-frame-bg">
<div id="tree"></div>
Expand Down Expand Up @@ -90,8 +92,10 @@
href="https://fonts.googleapis.com/css2?family=Inria+Serif:ital@1&family=Lexend+Deca:wght@600&family=Open+Sans:wght@300;400;600;700;800&display=swap"
rel="stylesheet"
/> -->
<link href="https://fonts.googleapis.com/css2?family=PT+Serif:wght@400;700&display=swap" rel="stylesheet">

<link
href="https://fonts.googleapis.com/css2?family=PT+Serif:wght@400;700&display=swap"
rel="stylesheet"
/>
</head>
<body>
<div id="tree"></div>
Expand Down
4 changes: 2 additions & 2 deletions public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,6 @@
"Provide Quantity range between 1-2": "Fournir une gamme de quantité comprise entre 1-2",
"Provide Professional_Skills range between 1-2": "Fournir une gamme de compétences professionnelles comprise entre 1-2",
"Sprint Ratings": "Sprint Notations",
"Please wait to be added to a program or cohort":"Veuillez attendre d'être ajouté à un programme ou à une cohorte",
"Enter all the required information":"Entrez toutes les informations requises"
"Please wait to be added to a program or cohort": "Veuillez attendre d'être ajouté à un programme ou à une cohorte",
"Enter all the required information": "Entrez toutes les informations requises"
}
20 changes: 10 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ function App() {
return (
<div className="min-h-screen">
<TicketsProvider>
<TraineesProvider>
<Router>
<ScrollToTop>
<Routes>
<Route path="/" element={<LandingPage />} />
<Route path="/*" element={<MainRoutes />} />
</Routes>
</ScrollToTop>
</Router>
</TraineesProvider>
<TraineesProvider>
<Router>
<ScrollToTop>
<Routes>
<Route path="/" element={<LandingPage />} />
<Route path="/*" element={<MainRoutes />} />
</Routes>
</ScrollToTop>
</Router>
</TraineesProvider>
</TicketsProvider>
</div>
);
Expand Down
32 changes: 32 additions & 0 deletions src/Mutations/ActionDropdownCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import ActionDropdown from '../components/ActionDropdown';

interface ActionDropdownCellProps {
row: {
original: any;
};
onView: (ticket: any) => void;
onEdit?: (id: string) => void;
onDelete?: (id: string) => void;
canEditDelete: boolean;
}

function ActionDropdownCell({
row,
onView,
onEdit,
onDelete,
canEditDelete,
}: ActionDropdownCellProps) {
return (
<ActionDropdown
onView={() => onView(row.original)}
onEdit={canEditDelete ? () => onEdit?.(row.original.id) : undefined}
onDelete={canEditDelete ? () => onDelete?.(row.original.id) : undefined}
canEditDelete={canEditDelete}
id={row.original.id}
/>
);
}

export default ActionDropdownCell;
2 changes: 1 addition & 1 deletion src/Mutations/User.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,4 @@ export const DROP_TTL_USER = gql`
dropTTLUser(email: $email, reason: $reason)
}
`;
export default GET_PROFILE;
export default GET_PROFILE;
4 changes: 2 additions & 2 deletions src/Mutations/help.mutation.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { gql } from '@apollo/client';

const CREATE_TICKET = gql`
mutation CreateTicket($subject: String!, $message: String!) {
createTicket(subject: $subject, message: $message) {
mutation CreateTicket($subject: String!, $message: String!, $assignee: ID!) {
createTicket(subject: $subject, message: $message, assignee: $assignee) {
responseMsg
}
}
Expand Down
111 changes: 111 additions & 0 deletions src/components/ActionDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, { useState } from 'react';
import {
FaEllipsisV,
FaEye,
FaEdit,
FaTrashAlt,
FaClipboard,
} from 'react-icons/fa';
import { toast } from 'react-toastify';

interface ActionDropdownProps {
onView: () => void;
onEdit?: () => void;
onDelete?: () => void;
canEditDelete: boolean;
id?: string;
}

function ActionDropdown({
onView,
onEdit,
onDelete,
canEditDelete,
id,
}: ActionDropdownProps) {
const [isOpen, setIsOpen] = useState(false);

const toggleDropdown = () => setIsOpen(!isOpen);

const copyToClipboard = (text: any) => {
navigator.clipboard
.writeText(text)
.then(() => {
toast.success('ID copied to clipboard!');
})
.catch((err) => {
toast.error(`Failed to copy: ${err}`);
});
};

return (
<div className="relative">
<button
type="button"
aria-label="Open actions menu"
className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
onClick={toggleDropdown}
>
<FaEllipsisV className="text-2xl" />
</button>
{isOpen && (
<div className="fixed z-10 w-48 mt-2 bg-white border border-gray-200 rounded-md shadow-lg right-10 dark:bg-gray-800 dark:border-gray-700">
<button
type="button"
aria-label="View item"
onClick={() => {
onView();
setIsOpen(false);
}}
className="flex items-center w-full px-4 py-2 text-sm text-blue-600 hover:bg-blue-100 dark:text-blue-400 dark:hover:bg-blue-700"
>
<FaEye className="mr-2" />
View
</button>
{canEditDelete && (
<>
<button
type="button"
aria-label="Edit item"
onClick={() => {
onEdit?.();
setIsOpen(false);
}}
className="flex items-center w-full px-4 py-2 text-sm text-yellow-600 hover:bg-yellow-100 dark:text-yellow-400 dark:hover:bg-yellow-700"
>
<FaEdit className="mr-2" />
Edit
</button>
<button
type="button"
aria-label="Delete item"
onClick={() => {
onDelete?.();
setIsOpen(false);
}}
className="flex items-center w-full px-4 py-2 text-sm text-red-600 hover:bg-red-100 dark:text-red-400 dark:hover:bg-red-700"
>
<FaTrashAlt className="mr-2" />
Delete
</button>
</>
)}
<button
type="button"
aria-label="Copy ID"
onClick={() => {
copyToClipboard(id);
setIsOpen(false);
}}
className="flex items-center w-full px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
>
<FaClipboard className="mr-2" />
Copy ID
</button>
</div>
)}
</div>
);
}

export default ActionDropdown;
5 changes: 1 addition & 4 deletions src/components/AttendanceStatistics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ function BarChart() {

return (
<div className="bg-white dark:bg-dark-bg shadow-lg px-5 py-8 rounded-md w-full font-serif">
<div className="">
hello

</div>
<div className="">hello</div>
</div>
);
}
Expand Down
17 changes: 9 additions & 8 deletions src/components/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ const Calendar = () => {
<>
{/* =========================== Start:: RegisterTraineeModel =========================== */}
<div
className={`font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${addEventModel === true ? 'block' : 'hidden'
}`}
className={`font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${
addEventModel === true ? 'block' : 'hidden'
}`}
>
<div className="bg-indigo-100 dark:bg-dark-bg w-full sm:w-3/4 md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8">
<div className="card-title w-full flex flex-wrap justify-center items-center ">
Expand Down Expand Up @@ -155,9 +156,9 @@ const Calendar = () => {
value={newEvent.hostName}
onChange /* istanbul ignore next */={(e) =>
/* istanbul ignore next */ setNewEvent({
...newEvent,
hostName: e.target.value,
})
...newEvent,
hostName: e.target.value,
})
}
/>
</div>
Expand All @@ -172,9 +173,9 @@ const Calendar = () => {
selected={newEvent.start}
onChange /* istanbul ignore next */={(start: any) =>
/* istanbul ignore next */ setNewEvent({
...newEvent,
start,
})
...newEvent,
start,
})
}
/>
</div>
Expand Down
64 changes: 64 additions & 0 deletions src/components/ConfirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* eslint-disable react/function-component-definition */
import React, { useState } from 'react';
import { toast } from 'react-toastify';

interface ConfirmationModalProps {
isOpen: boolean;
onConfirm: () => void;
onCancel: () => void;
message: string;
}

const ConfirmationModal: React.FC<ConfirmationModalProps> = ({
isOpen,
onConfirm,
onCancel,
message,
}) => {
const [loading, setLoading] = useState(false);

if (!isOpen) return null;

const handleConfirm = async () => {
setLoading(true);
try {
onConfirm();
} catch (error) {
toast.error('Failed to confirm action. Please try again.');
} finally {
setLoading(false);
}
};

return (
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
<div className="w-full max-w-sm p-6 bg-white rounded-lg shadow-lg dark:bg-gray-800 dark:shadow-gray-700">
<h2 className="mb-4 text-2xl font-bold text-gray-900 dark:text-gray-100">
Confirm Action
</h2>
<p className="mb-4 text-gray-700 dark:text-gray-300">{message}</p>
<div className="flex justify-end space-x-4">
<button
type="button"
onClick={onCancel}
className="px-4 py-2 text-white bg-gray-500 rounded hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-400 dark:bg-gray-600 dark:hover:bg-gray-700 dark:focus:ring-gray-500"
>
Cancel
</button>
<button
onClick={handleConfirm}
type="button"
className={`px-4 py-2 text-white rounded hover:bg-red-600 focus:outline-none focus:ring-2 ${
loading ? 'bg-red-400 cursor-not-allowed' : 'bg-red-500'
} dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-500`}
disabled={loading}
>
{loading ? 'Processing...' : 'Confirm'}
</button>
</div>
</div>
</div>
);
};

export default ConfirmationModal;
24 changes: 11 additions & 13 deletions src/components/CoordinatorCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,23 +164,21 @@ function ManagerCard() {
});

return (
<div
className="px-4 md:px-0 pb-20 w-full dark:bg-dark-frame-bg dark:text-black h-full flex overflow-x-auto "
>
{loading ? (
<div className="flex items-center justify-center w-full h-full">
<div className="spinner" />
</div>
) : (
<div className="pl-10 flex">
{teamData &&
<div className="px-4 md:px-0 pb-20 w-full dark:bg-dark-frame-bg dark:text-black h-full flex overflow-x-auto ">
{loading ? (
<div className="flex items-center justify-center w-full h-full">
<div className="spinner" />
</div>
) : (
<div className="pl-10 flex">
{teamData &&
teamData.map((teamProps: any, index: number) => (
<Link key={index} to={`/team/${(teamProps.teamname)}`}>
<Link key={index} to={`/team/${teamProps.teamname}`}>
<Card {...teamProps} />
</Link>
))}
</div>
)}
</div>
)}
</div>
);
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/CreateOrganizationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ export default function CreateOrganizationModal({

return (
<div
className={`font-serif h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${createOrganizationModel === true ? 'block' : 'hidden'
}`}
className={`font-serif h-screen w-screen bg-black fixed top-0 left-0 z-20 bg-opacity-30 backdrop-blur-sm flex items-center justify-center overflow-auto p-4 ${
createOrganizationModel === true ? 'block' : 'hidden'
}`}
>
<div className="bg-white dark:bg-dark-bg w-screen md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8">
<div className="card-title w-full flex flex-wrap justify-center items-center ">
Expand Down
Loading

0 comments on commit 40370c5

Please sign in to comment.