Skip to content

Commit

Permalink
Merge branch 'CI/CD-workflow' of https://github.com/ELEF-TQ/Vivo_Energy
Browse files Browse the repository at this point in the history
… into CI/CD-workflow
  • Loading branch information
Oussama-Sfiri committed Apr 28, 2024
2 parents fed5dc6 + 4ae9b5a commit 30e5da3
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vercel
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Vivo Energy

## Overview

Vivo Energy is a web application designed to streamline operations for fuel station management. It consists of two main components:

- **Client (Frontend)**: Built with React and Vite, this component provides a user-friendly interface for customers and administrators to interact with the system.
- **Server (Backend)**: Powered by NestJS, the server manages the business logic and interacts with the database to handle user requests and data management.

## Features

- **User Authentication**: Secure login and registration system for customers and administrators.
- **Client Management**: Manage client profiles and track client activities.
- **Fuel Station Management**: Administer fuel station operations, including fuel sales, inventory management, and staff management.
- **Reporting and Analytics**: Generate reports and analyze data to gain insights into business performance.

## Getting Started

To get started with Vivo Energy, follow these steps:

1. Clone this repository to your local machine.
2. Navigate to the `client` directory and run `yarn install` to install dependencies.
3. Navigate to the `server` directory and run `yarn install` to install server dependencies.
4. Configure environment variables in the `.env` file located in the `server` directory.
5. Start the client and server applications by running `yarn dev` in their respective directories.

## Contributing

We welcome contributions from the community to help improve Vivo Energy. If you'd like to contribute, please follow these guidelines:

1. Fork the repository and create a new branch for your feature or bug fix.
2. Make your changes and ensure they adhere to the project's coding style and guidelines.
3. Write tests to cover your changes if applicable.
4. Submit a pull request with a clear description of your changes and the problem they solve.

## License

This project is licensed under the [MIT License](LICENSE).
9 changes: 5 additions & 4 deletions client/src/components/modals/QRScannerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const QRScannerModal: React.FC<QRScannerModalProps> = ({ open, onClose, onScan }
onClose();
Swal.fire({
icon: 'success',
title: 'QR Code Scanned!',
text: `Scanned Data: ${data}`,
title: 'QR Code Scanner!',
text: `Code de Pompiste: ${data}`,
});
}
}, 1000);
Expand All @@ -38,9 +38,10 @@ const QRScannerModal: React.FC<QRScannerModalProps> = ({ open, onClose, onScan }
onClose={onClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
className="modal-QR"
>
<div className='modal-container'>
<div className='modal-content'>
<div className='modal-container-QR'>
<div className='modal-content-QR'>
<Scanner
onResult={handleScanResult}
onError={(error: { message: any }) => console.log(error?.message)}
Expand Down
7 changes: 5 additions & 2 deletions client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,14 @@ img {
border-radius: 8px;
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.2);
padding: 20px;
width: fit-content;
width: 500px;
max-width: 90%; /* Example max-width, adjust as needed */
width: 500px; /* Fallback width for older browsers */
max-height: 90vh; /* Example max-height, adjust as needed */
overflow-y: auto; /* Enable vertical scroll when content exceeds height */
animation: slideIn 0.3s forwards;
}


.modal__delete {
animation: slideIn 0.3s forwards;
}
Expand Down
13 changes: 11 additions & 2 deletions client/src/pages/Admin/GestAdmins/Admins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const Admins: React.FC = () => {
const [selectedId, setSelectedId] = useState(null);
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const [selectAllChecked, setSelectAllChecked] = useState(false);
const [searchValue, setSearchValue] = useState('');

// Checkbox handling
const handleSelectAllChange = (e: { target: { checked: any } }) => {
Expand All @@ -39,6 +40,12 @@ const Admins: React.FC = () => {
);
};

// Fonction de filtrage des clients en fonction de la valeur de recherche
const filteredAdmins = admins.filter((admin: any) =>
admin.username.toLowerCase().includes(searchValue.toLowerCase()) ||
admin.CIN?.toLowerCase().includes(searchValue.toLowerCase())
);

useEffect(() => {
dispatch(fetchAdmins());
}, []);
Expand Down Expand Up @@ -73,7 +80,7 @@ const Admins: React.FC = () => {
<path fillRule="evenodd" clipRule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" />
</svg>
</div>
<input type="text" id="simple-search" placeholder="Search for products" required className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
<input value={searchValue} onChange={(e) => setSearchValue(e.target.value)} type="text" id="simple-search" placeholder="Search for products" required className="outline-0 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
</div>
</form>
</div>
Expand Down Expand Up @@ -120,14 +127,15 @@ const Admins: React.FC = () => {
</th>
<th scope="col" className="p-4 ">Admin</th>
<th scope="col" className="p-4 ">Nom</th>
<th scope="col" className="p-4 ">CIN</th>
<th scope="col" className="p-4 ">Email</th>
<th scope="col" className="p-4 ">phone</th>
<th scope="col" className="p-4 ">role</th>
<th scope="col" className="p-4 ">Actions</th>
</tr>
</thead>
<tbody>
{admins?.map((admin :any ) => (
{filteredAdmins?.map((admin :any ) => (
<tr key={admin._id} className="border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700">
<td className="p-4 w-4">
<div className="flex items-center">
Expand Down Expand Up @@ -155,6 +163,7 @@ const Admins: React.FC = () => {
</div>
</th>
<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">{admin.username}</td>
<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">{admin.CIN}</td>
<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">{admin.email}</td>
<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">{admin.phone}</td>
<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">{admin?.adminRole?.name}</td>
Expand Down
11 changes: 8 additions & 3 deletions client/src/pages/Admin/GestClients/Clients.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Client : React.FC = () => {
const [selectedId, setSelectedId] = useState(null);
const [selectedIds , setSelectedIds] = useState<string[]>([]);;
const [selectAllChecked, setSelectAllChecked] = useState(false);

const [searchValue, setSearchValue] = useState('');


// Checkbox handling
Expand All @@ -43,6 +43,11 @@ const Client : React.FC = () => {
);
};

// Fonction de filtrage des clients en fonction de la valeur de recherche
const filteredClients = clients.filter((client: any) =>
client.username.toLowerCase().includes(searchValue.toLowerCase()) ||
client.CIN?.toLowerCase().includes(searchValue.toLowerCase())
);

useEffect(()=> {
dispatch(fetchClients());
Expand Down Expand Up @@ -79,7 +84,7 @@ const Client : React.FC = () => {
<path fillRule="evenodd" clipRule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" />
</svg>
</div>
<input type="text" id="simple-search" placeholder="Search " required className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
<input value={searchValue} onChange={(e) => setSearchValue(e.target.value)} type="text" id="simple-search" placeholder="Search " required className="outline-0 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
</div>
</form>
</div>
Expand Down Expand Up @@ -133,7 +138,7 @@ const Client : React.FC = () => {
</tr>
</thead>
<tbody>
{clients?.map((client :any ) => (
{filteredClients?.map((client :any ) => (
<tr key={client._id} className="border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700">
<td className="p-4 w-4">
<div className="flex items-center">
Expand Down
9 changes: 7 additions & 2 deletions client/src/pages/Admin/GestCoupons/Coupon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const Coupon : React.FC = () => {
const [selectedId, setSelectedId] = useState(null);
const [selectedIds , setSelectedIds] = useState<string[]>([]);;
const [selectAllChecked, setSelectAllChecked] = useState(false);
const [searchValue, setSearchValue] = useState('');

const getCouponStatus = (expirationDate: string): StatusLabelProps => {
const currentDate = new Date();
Expand Down Expand Up @@ -67,6 +68,10 @@ const Coupon : React.FC = () => {
return `${day}-${month}-${year}`;
}

// Fonction de filtrage des clients en fonction de la valeur de recherche
const filteredCoupons = coupons.filter((coupon: any) =>
coupon.code.toLowerCase().includes(searchValue.toLowerCase())
);

useEffect(()=> {
dispatch(fetchAllCoupons());
Expand Down Expand Up @@ -101,7 +106,7 @@ const Coupon : React.FC = () => {
<path fillRule="evenodd" clipRule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" />
</svg>
</div>
<input type="text" id="simple-search" placeholder="Search" required className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
<input value={searchValue} onChange={(e) => setSearchValue(e.target.value)} type="text" id="simple-search" placeholder="Search" required className="outline-0 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
</div>
</form>
</div>
Expand Down Expand Up @@ -156,7 +161,7 @@ const Coupon : React.FC = () => {
</tr>
</thead>
<tbody>
{coupons?.map((coupon :any ) => (
{filteredCoupons?.map((coupon :any ) => (
<tr key={coupon._id} className="border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700">
<td className="p-4 w-4">
<div className="flex items-center">
Expand Down
11 changes: 9 additions & 2 deletions client/src/pages/Admin/GestPompistes/Pompiste.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const Pompiste: React.FC = () => {
const [selectedId, setSelectedId] = useState(null);
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const [selectAllChecked, setSelectAllChecked] = useState(false);
const [searchValue, setSearchValue] = useState('');

// Checkbox handling
const handleSelectAllChange = (e: { target: { checked: any } }) => {
Expand All @@ -40,6 +41,12 @@ const Pompiste: React.FC = () => {
);
};

// Fonction de filtrage des clients en fonction de la valeur de recherche
const filteredPompistes = pompistes.filter((pompiste: any) =>
pompiste.username.toLowerCase().includes(searchValue.toLowerCase()) ||
pompiste.matriculeRH.toLowerCase().includes(searchValue.toLowerCase())
);

useEffect(() => {
dispatch(fetchPompistes());
}, []);
Expand Down Expand Up @@ -73,7 +80,7 @@ const Pompiste: React.FC = () => {
<path fillRule="evenodd" clipRule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" />
</svg>
</div>
<input type="text" id="simple-search" placeholder="Search " required className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
<input value={searchValue} onChange={(e) => setSearchValue(e.target.value)} type="text" id="simple-search" placeholder="Search " required className="outline-0 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
</div>
</form>
</div>
Expand Down Expand Up @@ -127,7 +134,7 @@ const Pompiste: React.FC = () => {
</tr>
</thead>
<tbody>
{pompistes?.map((pompiste :any ) => (
{filteredPompistes?.map((pompiste :any ) => (
<tr key={pompiste._id} className="border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700">
<td className="p-4 w-4">
<div className="flex items-center">
Expand Down
17 changes: 12 additions & 5 deletions client/src/pages/Admin/GestServices/Services.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const Service: React.FC = () => {
const [selectedId, setSelectedId] = useState(null);
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const [selectAllChecked, setSelectAllChecked] = useState(false);
const [searchValue, setSearchValue] = useState('');


// Checkbox handling
const handleSelectAllChange = (e: { target: { checked: any } }) => {
Expand All @@ -36,6 +38,11 @@ const Service: React.FC = () => {
);
};

// Fonction de filtrage des clients en fonction de la valeur de recherche
const filteredServices = services.filter((service: any) =>
service.nom.toLowerCase().includes(searchValue.toLowerCase())
);

useEffect(() => {
dispatch(fetchServices());
}, []);
Expand All @@ -48,7 +55,7 @@ const Service: React.FC = () => {
) : (
<section className=" p-3 sm:p-5 antialiased">
<div className="mx-auto max-w-screen-2xl px-4 lg:px-12">
<div className="bg-white dark:bg-gray-800 relative shadow-md sm:rounded-lg overflow-hidden">
<div className="bg-white dark:bg-gray-800 relative shadow-lg sm:rounded-lg overflow-hidden">
<div className="flex flex-col md:flex-row md:items-center md:justify-between space-y-3 md:space-y-0 md:space-x-4 p-4">
<div className="flex-1 flex items-center space-x-2">
<h5>
Expand All @@ -69,7 +76,7 @@ const Service: React.FC = () => {
<path fillRule="evenodd" clipRule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" />
</svg>
</div>
<input type="text" id="simple-search" placeholder="Search" required className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
<input value={searchValue} onChange={(e) => setSearchValue(e.target.value)} type="text" id="simple-search" placeholder="Search" required className="outline-0 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" />
</div>
</form>
</div>
Expand Down Expand Up @@ -121,7 +128,7 @@ const Service: React.FC = () => {
</tr>
</thead>
<tbody>
{services?.map((service :any ) => (
{filteredServices?.map((service :any ) => (
<tr key={service._id} className="border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700">
<td className="p-4 w-4">
<div className="flex items-center">
Expand All @@ -144,10 +151,10 @@ const Service: React.FC = () => {
<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">{service.nom}</td>

<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{service.prix}
{service.prix} Dhs
</td>

<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">{service.description}</td>
<td className="px-4 py-3 font-medium text-gray-900 whitespace-normal break-words dark:text-white">{service.description}</td>

<td className="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">
<div className="flex items-center justify-center space-x-4">
Expand Down
31 changes: 16 additions & 15 deletions client/src/pages/public/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,25 @@
border-radius: 50%;
}

.transition-container {
transition: opacity 0.3s ease-in-out;
}


.modal-container {
position: absolute;
top: 50%;
left: 30%;
transform: translate(50% , -50%);
height: 20rem;
width: 20rem;

.modal-QR {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
}

.modal-content {
background-color: var(--primary-color);
padding: 20px;
.modal-container-QR {
border-radius: 8px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);

padding: 20px;
}

.modal-content-QR {
width: 300px; /* Example width, adjust as needed */
height: 200px; /* Example height, adjust as needed */
}

0 comments on commit 30e5da3

Please sign in to comment.