Compare commits

...

14 Commits

Author SHA1 Message Date
victorAnumudu fecae9d626 file list refresh and scroll bar added 2026-01-05 14:37:19 +01:00
CHIEFSOFT\ameye 51c2e4b568 Added report starter 2026-01-03 12:05:42 -05:00
CHIEFSOFT\ameye 756c084059 Added report starter 2026-01-03 11:04:15 -05:00
CHIEFSOFT\ameye 064973e190 Added report starter 2026-01-03 10:24:34 -05:00
CHIEFSOFT\ameye d165e9dc0f upload page 2026-01-01 12:19:36 -05:00
CHIEFSOFT\ameye 77109e8369 Added Media starter icons 2026-01-01 11:23:16 -05:00
CHIEFSOFT\ameye 2924401c9b media files 2026-01-01 01:05:48 -05:00
CHIEFSOFT\ameye f6c2b1129d server path 2025-12-28 14:34:21 -05:00
CHIEFSOFT\ameye 8ba167a17c panel values 2025-12-28 14:13:16 -05:00
CHIEFSOFT\ameye 7f65b286b1 Media upload 2025-12-28 10:58:56 -05:00
CHIEFSOFT\ameye afc9e5be0f Added Media starter 2025-12-14 14:26:11 -05:00
ameye 7aefb555ed Merge branch 'user-picture' of MERMS/MermsPanelReactJS into master 2025-12-02 22:58:40 +00:00
victorAnumudu 325d28c1a8 user profile picture link added 2025-12-02 21:42:41 +01:00
ameye 25269a44c3 Merge branch 'calendar-refresh' of MERMS/MermsPanelReactJS into master 2025-11-28 23:15:35 +00:00
20 changed files with 801 additions and 70 deletions
+2
View File
@@ -26,6 +26,7 @@ import ProfileCompletePage from './views/ProfileCompletePage';
import SubscribePage from './views/Subscribe'
import StartPage from "./views/StartPage";
import TrafficPage from "./views/TrafficPage";
import MyMediaPage from './views/MyMediaPage.jsx';
function AppRouters() {
return (
@@ -52,6 +53,7 @@ function AppRouters() {
<Route path={siteLinks.profile_complete} element={<ProfileCompletePage/>}/>
<Route path={siteLinks.product} element={<ProductPage/>}/>
<Route path={siteLinks.reports} element={<ReportsPage/>}/>
<Route path={siteLinks.my_media} element={<MyMediaPage />}/>
<Route path={siteLinks.comments} element={<CommentsPage/>}/>
<Route path={siteLinks.contacts} element={<ContactsPage/>}/>
<Route path={siteLinks.user} element={<UserPage/>}/>
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

@@ -11,7 +11,7 @@ export default function UserFooter(){
<p>&copy; Copyright {year}. All rights reserved.</p>
</div>
<div className="col col-sm-6 ml-sm-auto text-center text-sm-right">
<p>A division of <i className="fa fa-key text-danger mx-1"></i> autoMedSys A.I.</p>
<p>A division of autoMedSys A.I.</p>
</div>
</div>
</footer>
@@ -74,7 +74,11 @@ export default function UserHeader(){
<ul className="navbar-nav nav-right ml-auto">
<li className="nav-item user-profile">
<a onClick={toggleMenu} className="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdow">
<img src={getImage('profile-pic-circle.png')} alt="avtar-img" />
<img
src={userDetails?.picture ? userDetails?.picture : getImage('profile-pic-circle.png')}
// src={getImage('profile-pic-circle.png')}
alt="avtar-img"
/>
<span className="bg-success user-status"></span>
</a>
<div ref={nav_menu} onClick={toggleMenu} className="dropdown-menu animated fadeIn">
@@ -48,6 +48,7 @@ export default function UserMenu() {
</div>
</Link>
<ul id="collapseTwo" className="collapse" aria-labelledby="headingTwo" data-bs-parent="#sidebarNav">
<li className={`${pathname == siteLinks.my_media ? 'active' : ''}`}><Link to={siteLinks.my_media}>Files and Media</Link></li>
<li className={`${pathname == siteLinks.subscription ? 'active' : ''}`}><Link to={siteLinks.subscription}>Subscription</Link></li>
<li className={`${pathname == siteLinks.settings ? 'active' : ''}`}><Link to={siteLinks.settings}>Settings</Link></li>
</ul>
+234
View File
@@ -0,0 +1,234 @@
import React from "react";
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
import {useState, useRef} from "react";
import {useQuery, useMutation, useQueryClient} from "@tanstack/react-query";
import queryKeys from "../../services/queryKeys";
import {getMediaFileList, uploadFile} from "../../services/services";
import getImage from "../../utils/getImage";
export default function MyMedia() {
const queryClient = useQueryClient()
const basePath = process.env.REACT_APP_MAIN_API
const [selectedFile, setSelectedFile] = useState(null);
const [message, setMessage] = useState('');
const [imageLink, setImageLink] = useState('')
console.log('imageLink', imageLink)
// Function to handle file selection
const handleFileChange = (event) => {
setSelectedFile(event.target.files[0]);
setMessage('');
};
// Function to handle the upload to the API
const _handleUpload = async () => {
if (!selectedFile) {
setMessage('Please select a file first!');
return;
}
const formData = new FormData();
// 'file' is the field name that your API endpoint expects
formData.append('file', selectedFile);
formData.append("member_uid", localStorage.getItem('uid'));
formData.append("token", localStorage.getItem('token'));
try {
// Replace with your actual API endpoint URL
const apiEndpoint = basePath + '/upload/webfiles';
const response = await fetch(apiEndpoint, {
method: 'POST',
// The browser automatically sets the 'Content-Type' header to
// 'multipart/form-data' when you provide a FormData object as the body,
// which is required for file uploads.
body: formData,
});
if (response.ok) {
const result = await response.json();
setMessage('File uploaded successfully!');
console.log('Success:', result);
} else {
setMessage('Upload failed.');
console.error('Upload failed:', response.statusText);
}
} catch (error) {
setMessage('An error occurred during the upload.');
console.error('Error:', error);
}
}
const uploadFileMutation = useMutation({
mutationFn: (fields) => {
if(!fields.file){
throw({message: 'Please select a file first!'})
}
return uploadFile(fields)
},
onSuccess: (res) => {
// console.log('res', res.data)
// if(res.data.resultCode != '0' || !res?.data?.pending_uid){
// throw({message: res?.data?.resultDescription})
// }
setSelectedFile(null)
queryClient.refetchQueries({
queryKey: [...queryKeys.my_files],
// type: 'active',
// exact: true,
})
},
onSettled: () => {
setTimeout(()=>{
uploadFileMutation.reset()
}, 3000)
}
})
const handleUpload = () => {
let reqData = {
token: localStorage.getItem("token"), // USER TOKEN
member_uid: localStorage.getItem("uid"), // USER UID
file: selectedFile
};
// console.log(reqData)
uploadFileMutation.mutate(reqData)
}
const {data, isFetching, isError, error} = useQuery({
queryKey: queryKeys.my_files,
queryFn: () => {
let reqData = {
token: localStorage.getItem('token'), // USER TOKEN
uid: localStorage.getItem('uid') // USER UID
}
return getMediaFileList(reqData)
}
})
const mediaFileList = data?.data
//debugger;
return (
<>
<BreadcrumbComBS title='Files' paths={['Dashboard', 'Files']}/>
<div className="row">
<div className="col-xl-6 col-xxl-4 m-b-30">
<div className="card card-statistics h-50 mb-0 widget-support-list">
<div className="card-header">
<div className="card-heading">
<h4 className="card-title">Upload File</h4>
</div>
</div>
<div className="card-body pl-0 pr-0 scrollbar scroll_dark">
<div className="widget-text">
<div>
<input className="form-control form-control-sm" type="file"
onChange={handleFileChange}/>
{selectedFile && (
<div>
<h4>Selected File Details:</h4>
<ul>
<li>Name: {selectedFile.name}</li>
<li>Type: {selectedFile.type}</li>
<li>Size: {selectedFile.size} bytes</li>
</ul>
<div style={{width: '100%', textAlign: 'right'}}>
<button
className="btn btn-square btn-inverse-light btn-xs d-inline-block mt-2 mb-0"
onClick={handleUpload} disabled={!selectedFile || uploadFileMutation.isPending || uploadFileMutation.isSuccess}>
Upload
</button>
</div>
<>
{/* {message && <p>{message}</p>} */}
<p>{uploadFileMutation.isPending ? 'uploading...' : uploadFileMutation.isError ? uploadFileMutation?.error?.message : uploadFileMutation.isSuccess ? 'File Uploaded' : ''}</p>
</>
</div>
)}
</div>
</div>
</div>
</div>
</div>
<div className="col-xl-6 col-xxl-4 m-b-30">
<div className="card card-statistics h-100 mb-0 widget-downloads-list" style={{}}>
<div className="card-header d-flex justify-content-between">
<div className="card-heading">
<div className="card-heading">
<h4 className="card-title">Files List</h4>
</div>
</div>
</div>
{isFetching ?
<>
<div className="col-12">
<p className='text-mute'>Loading...</p>
</div>
</>
: isError ?
<div className="col-12">
<p className='text-danger'>{error?.message}</p>
</div>
:
<div className="card-body scrollbar scroll_dark" style={{minHeight: '400px', maxHeight: '500px', overflowY: 'auto'}}>
{mediaFileList && mediaFileList?.file_list && mediaFileList?.file_list.map((item, index) => {
const file_url = (mediaFileList?.media_server + "/" + item?.file_group + "/" + item?.file_uid + "/" + item.filename).toLowerCase();
const avtarImage =
item?.file_type === undefined
? "icons/01.png"
: "icons/" + item.file_type + ".png";
return (<div key={index} className="widget-text">
<div className="media align-items-center" onClick={()=>setImageLink(file_url)} style={{cursor: 'pointer'}}>
<img src={getImage(avtarImage)}
// src={`assets/img/file-icon/${item.file_type}.png`}
className="img-fluid"
alt={`${item.file_type}`}/>
<div className="media-body">
<h4 className="mb-0 ml-3">{item.filename}</h4>
</div>
<div>
<a href={`${file_url}`} target='_blank'
className="btn btn-icon btn-round btn-outline-success">
<i className="ti ti-download"></i>
</a>
<a href="" className="btn btn-icon btn-round btn-outline-danger ml-2">
<i className="ti ti-close"></i>
</a>
</div>
</div>
</div>)
})
}
</div>
}
</div>
</div>
<div className="col-xl-6 col-xxl-4 m-b-30">
<div className="card card-statistics h-100 mb-0 widget-branches-list">
<div className="card-header">
<div className="card-heading">
<h4 className="card-title">Preview</h4>
</div>
</div>
<div className="card-body d-flex justify-content-center align-items-center pl-0 pr-0 scrollbar scroll_dark">
{imageLink &&
<img src={imageLink} alt='file-image' />
}
</div>
</div>
</div>
</div>
</>
)
}
@@ -0,0 +1,175 @@
import React from "react";
export default function PaymentReportTable() {
return (<>
{/*<div className="row">*/}
{/* <div className="col-md-12 m-b-30">*/}
{/* <div className="d-block d-sm-flex flex-nowrap align-items-center">*/}
{/* <div className="page-title mb-2 mb-sm-0">*/}
{/* <h4>Payments Report</h4>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
<div className="row">
<div className="col-lg-12">
<div className="card card-statistics">
<div className="card-body">
<div className="page-title mb-2 mb-sm-0">
<h4>Payments Report</h4>
</div>
<div className="export-table-wrapper table-responsive">
<table id="export-table" className="table table-bordered">
<thead className="thead-light">
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>$433,060</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>33</td>
<td>2008/11/28</td>
<td>$162,700</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>61</td>
<td>2012/12/02</td>
<td>$372,000</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Sales Assistant</td>
<td>San Francisco</td>
<td>59</td>
<td>2012/08/06</td>
<td>$137,500</td>
</tr>
<tr>
<td>Rhona Davidson</td>
<td>Integration Specialist</td>
<td>Tokyo</td>
<td>55</td>
<td>2010/10/14</td>
<td>$327,900</td>
</tr>
<tr>
<td>Colleen Hurst</td>
<td>Javascript Developer</td>
<td>San Francisco</td>
<td>39</td>
<td>2009/09/15</td>
<td>$205,500</td>
</tr>
<tr>
<td>Sonya Frost</td>
<td>Software Engineer</td>
<td>Edinburgh</td>
<td>23</td>
<td>2008/12/13</td>
<td>$103,600</td>
</tr>
<tr>
<td>Jena Gaines</td>
<td>Office Manager</td>
<td>London</td>
<td>30</td>
<td>2008/12/19</td>
<td>$90,560</td>
</tr>
<tr>
<td>Quinn Flynn</td>
<td>Support Lead</td>
<td>Edinburgh</td>
<td>22</td>
<td>2013/03/03</td>
<td>$342,000</td>
</tr>
<tr>
<td>Charde Marshall</td>
<td>Regional Director</td>
<td>San Francisco</td>
<td>36</td>
<td>2008/10/16</td>
<td>$470,600</td>
</tr>
<tr>
<td>Haley Kennedy</td>
<td>Senior Marketing Designer</td>
<td>London</td>
<td>43</td>
<td>2012/12/18</td>
<td>$313,500</td>
</tr>
<tr>
<td>Tatyana Fitzpatrick</td>
<td>Regional Director</td>
<td>London</td>
<td>19</td>
<td>2010/03/17</td>
<td>$385,750</td>
</tr>
<tr>
<td>Michael Silva</td>
<td>Marketing Designer</td>
<td>London</td>
<td>66</td>
<td>2012/11/27</td>
<td>$198,500</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</>)
}
@@ -0,0 +1,172 @@
import React from "react";
export default function ProductReportTable() {
return (<>
<div className="row">
<div className="col-md-12 m-b-30">
<div className="d-block d-sm-flex flex-nowrap align-items-center">
<div className="page-title mb-2 mb-sm-0">
<h4>Payments Report</h4>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-12">
<div className="card card-statistics">
<div className="card-body">
<div className="export-table-wrapper table-responsive">
<table id="export-table" className="table table-bordered">
<thead className="thead-light">
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>$433,060</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>33</td>
<td>2008/11/28</td>
<td>$162,700</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>61</td>
<td>2012/12/02</td>
<td>$372,000</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Sales Assistant</td>
<td>San Francisco</td>
<td>59</td>
<td>2012/08/06</td>
<td>$137,500</td>
</tr>
<tr>
<td>Rhona Davidson</td>
<td>Integration Specialist</td>
<td>Tokyo</td>
<td>55</td>
<td>2010/10/14</td>
<td>$327,900</td>
</tr>
<tr>
<td>Colleen Hurst</td>
<td>Javascript Developer</td>
<td>San Francisco</td>
<td>39</td>
<td>2009/09/15</td>
<td>$205,500</td>
</tr>
<tr>
<td>Sonya Frost</td>
<td>Software Engineer</td>
<td>Edinburgh</td>
<td>23</td>
<td>2008/12/13</td>
<td>$103,600</td>
</tr>
<tr>
<td>Jena Gaines</td>
<td>Office Manager</td>
<td>London</td>
<td>30</td>
<td>2008/12/19</td>
<td>$90,560</td>
</tr>
<tr>
<td>Quinn Flynn</td>
<td>Support Lead</td>
<td>Edinburgh</td>
<td>22</td>
<td>2013/03/03</td>
<td>$342,000</td>
</tr>
<tr>
<td>Charde Marshall</td>
<td>Regional Director</td>
<td>San Francisco</td>
<td>36</td>
<td>2008/10/16</td>
<td>$470,600</td>
</tr>
<tr>
<td>Haley Kennedy</td>
<td>Senior Marketing Designer</td>
<td>London</td>
<td>43</td>
<td>2012/12/18</td>
<td>$313,500</td>
</tr>
<tr>
<td>Tatyana Fitzpatrick</td>
<td>Regional Director</td>
<td>London</td>
<td>19</td>
<td>2010/03/17</td>
<td>$385,750</td>
</tr>
<tr>
<td>Michael Silva</td>
<td>Marketing Designer</td>
<td>London</td>
<td>66</td>
<td>2012/11/27</td>
<td>$198,500</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</>)
}
+39 -32
View File
@@ -1,20 +1,34 @@
import React from "react";
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
import {useQuery} from "@tanstack/react-query";
import queryKeys from "../../services/queryKeys";
import {getReportsTopicsList} from "../../services/services";
import PaymentReportTable from "./PaymentReportTable";
import ProductReportTable from "./ProductReportTable";
export default function Reports(){
export default function Reports() {
return(
const {data, isFetching, isError, error} = useQuery({
queryKey: queryKeys.my_files,
queryFn: () => {
let reqData = {
token: localStorage.getItem('token'), // USER TOKEN
uid: localStorage.getItem('uid') // USER UID
}
return getReportsTopicsList(reqData)
}
})
const reportTopicList = data?.data?.topics?.topics;
return (
<>
<BreadcrumbComBS title='Reports' paths={['Dashboard', 'Reports']} />
<BreadcrumbComBS title='Reports' paths={['Dashboard', 'Reports']}/>
<div className="row">
<div>
<div>
<div className="card card-statistics" style={{minHeight:'550px'}}>
<div className="card card-statistics" style={{minHeight: '550px'}}>
{/*<div className="card-header">*/}
{/* <div className="card-heading">*/}
{/* <h4 className="card-title"> Tab vertical </h4>*/}
@@ -23,31 +37,26 @@ export default function Reports(){
<div className="card-body">
<div className="tab tab-vertical">
<ul className="nav nav-tabs" role="tablist">
<li className="nav-item">
<a className="nav-link active show" id="home-09-tab" data-toggle="tab" href="#home-09" role="tab" aria-controls="home-09" aria-selected="true"> Home</a>
</li>
<li className="nav-item">
<a className="nav-link" id="profile-09-tab" data-toggle="tab" href="#profile-09" role="tab" aria-controls="profile-09" aria-selected="false"> Profile </a>
</li>
<li className="nav-item">
<a className="nav-link" id="portfolio-09-tab" data-toggle="tab" href="#portfolio-09" role="tab" aria-controls="portfolio-09" aria-selected="false">Portfolio </a>
</li>
<li className="nav-item">
<a className="nav-link" id="contact-09-tab" data-toggle="tab" href="#contact-09" role="tab" aria-controls="contact-09" aria-selected="false"> Contact </a>
</li>
{reportTopicList && reportTopicList.map((item, index) => {
return (
<li className="nav-item">
<a className="nav-link" id={`report-${item.url}-tab`}
data-toggle="tab" href={`#`} role="tab"
aria-controls="home-09" aria-selected="true"> {item.name}</a>
</li>
)
}
)
}
</ul>
<div className="tab-content">
<div className="tab-pane fade active show" id="home-09" role="tabpanel" aria-labelledby="home-09-tab">
<p>Positive pleasure-oriented goals are much more powerful motivators than negative fear-based ones. Although each is successful separately, the right combination of both is the most powerful motivational force known to humankind.Make a list of your achievements toward your long-term goal and remind yourself that intentions dont count, only actions.</p>
<div className="tab-pane fade active show" id="home-09" role="tabpanel"
aria-labelledby="home-09-tab">
{<PaymentReportTable/>}
</div>
<div className="tab-pane fade" id="profile-09" role="tabpanel" aria-labelledby="profile-09-tab">
<p>Reflect and experiment until you find the right combination of motivators for your personality and your personal goals. Do it today. Remind yourself of someone you know who died suddenly and the fact that there is no guarantee that tomorrow will come.</p>
</div>
<div className="tab-pane fade" id="portfolio-09" role="tabpanel" aria-labelledby="portfolio-09-tab">
<p>Commitment is something that comes from understanding that everything has its price and then having the willingness to pay that price. This is important because nobody wants to put significant effort into something, only to find out after the fact that the price was too high. We all know people who live this truth.Give yourself the power of responsibility.</p>
</div>
<div className="tab-pane fade" id="contact-09" role="tabpanel" aria-labelledby="contact-09-tab">
<p>I truly believe Augustines words are true and if you look at history you know it is true. There are many people in the world with amazing talents who realize only a small percentage of their potential. We all know people who live this truth.Give yourself the power of responsibility. Remind yourself the only thing stopping you is yourself.</p>
<div className="tab-pane fade" id="profile-09" role="tabpanel"
aria-labelledby="profile-09-tab">
{<ProductReportTable/>}
</div>
</div>
</div>
@@ -55,8 +64,6 @@ export default function Reports(){
</div>
</div>
</div>
</div>
</>
)
+1 -1
View File
@@ -52,7 +52,7 @@ export default function ProfileForm({data}) {
},
onSuccess: (res) => {
if(res.data.resultCode != '0'){
throw({message: res?.data?.resultDescription ? res?.data?.resultDescription : 'En error occured'})
throw({message: res?.data?.resultDescription ? res?.data?.resultDescription : 'An error occured'})
}
const account_name = res?.data?.personal_data?.account_name
dispatch(updateUserDetails({ account_name }));
+117
View File
@@ -0,0 +1,117 @@
import React, { memo, useRef, useState } from 'react'
// import { useSelector } from 'react-redux';
import getImage from '../../utils/getImage';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { uploadProfileImg } from '../../services/services';
import queryKeys from '../../services/queryKeys';
const ProfileImage = memo(({intialData}) => {
const queryClient = useQueryClient()
const [selectedImg, setSelectedImg] = useState(null)
// const {userDetails} = useSelector((state) => state?.userDetails); // CHECKS FOR ACTIVE USER DETAILS
const avtarImage = "avtar/merms-user.png";
// browser profile img
const browserImg = useRef(null);
const browseProfileImg = () => {
browserImg.current.click();
};
const profileImgChangeHandler = (event) => {
setSelectedImg(event.target.files[0])
}
const uploadProfileMutation = useMutation({
mutationFn: (fields) => {
if(!fields.img){
throw new Error('Please, select an image')
}
return uploadProfileImg(fields)
},
onSuccess: (res) => {
if(res.data.resultCode != '0'){
throw({message: res?.data?.resultDescription ? res?.data?.resultDescription : 'An error occured'})
}
// const account_name = res?.data?.personal_data?.account_name
// dispatch(updateUserDetails({ account_name }));
},
onSettled: ()=>{
setTimeout(() => {
queryClient.refetchQueries({
queryKey: [...queryKeys.profile_data], // type: 'active', // exact: true,
})
uploadProfileMutation.reset()
}, 3000);
}
})
const proceedToUpload = () => {
let reqData = {
token: localStorage.getItem('token'), // USER TOKEN
uid: localStorage.getItem('uid'), // USER UID
img: selectedImg
}
// console.log('reqData', reqData)
uploadProfileMutation.mutate(reqData)
}
return (
<div className="col-xl-3 pb-xl-0 pb-5 border-right">
<div className="page-account-profil pt-5">
<div className="profile-img text-center rounded-circle">
<div className="pt-5">
<div className="bg-img m-auto">
<img
src={selectedImg ? URL.createObjectURL(selectedImg) : intialData?.personal_data?.picture ? intialData?.personal_data?.picture : getImage(avtarImage)}
// src={getImage(avtarImage)}
className="img-fluid" alt="user"
/>
<input
ref={browserImg}
className='d-none'
type='file'
accept="image/*"
onChange={(e) => profileImgChangeHandler(e)}
id='profile-image'
/>
</div>
<div className="profile pt-4">
<h4 className="mb-1">{intialData?.personal_data?.lastname} {intialData?.personal_data?.firstname}</h4>
<div style={{padding: '10px'}}>
<hr/>
</div>
</div>
</div>
</div>
<div className="profile-btn text-center">
<div>
<button onClick={browseProfileImg} className="btn btn-light text-primary mb-2">Change
</button>
</div>
{selectedImg &&
<div>
<button onClick={proceedToUpload} disabled={uploadProfileMutation.isSuccess || uploadProfileMutation.isPending} className="btn btn-light text-primary mb-2">
{uploadProfileMutation.isPaused ? 'Upload...' : 'Upload New Avatar'}
</button>
</div>
}
{/* success or error message */}
{(uploadProfileMutation.isSuccess || uploadProfileMutation.isError) &&
<div>
<p className={`${uploadProfileMutation.isSuccess ? 'text-success' : 'text-danger'}`}>
{uploadProfileMutation.isSuccess ? 'Uploaded successfully' : uploadProfileMutation.error.message}
</p>
</div>
}
</div>
</div>
</div>
)
}
)
export default ProfileImage
+2 -31
View File
@@ -6,9 +6,9 @@ import { useQuery } from "@tanstack/react-query";
import { profileDetails } from "../../services/services";
import ProfileForm from "./ProfileForm";
import LinksForm from "./LinksForm";
import ProfileImage from "./ProfileImage";
export default function Settings() {
const avtarImage = "avtar/merms-user.png";
const [intialData, setInitialData] = useState({
external_links: {},
@@ -59,36 +59,7 @@ export default function Settings() {
<div className="card card-statistics">
<div className="card-body p-0" style={{backgroundColor: "#f9f9fb"}}>
<div className="row no-gutters">
<div className="col-xl-3 pb-xl-0 pb-5 border-right">
<div className="page-account-profil pt-5">
<div className="profile-img text-center rounded-circle">
<div className="pt-5">
<div className="bg-img m-auto">
{/*<img src="assets/img/avtar/01.jpg" className="img-fluid"*/}
{/* alt="users-avatar" />*/}
<img src={getImage(avtarImage)}
className="img-fluid" alt="user"/>
</div>
<div className="profile pt-4">
<h4 className="mb-1">{intialData?.personal_data?.lastname} {intialData?.personal_data?.firstname}</h4>
<div style={{padding: '10px'}}>
<hr/>
</div>
</div>
</div>
</div>
<div className="profile-btn text-center">
<div>
<button className="btn btn-light text-primary mb-2">Upload New Avatar
</button>
</div>
{/*<div>*/}
{/* <button className="btn btn-danger">Delete</button>*/}
{/*</div>*/}
</div>
</div>
</div>
<ProfileImage intialData={intialData} />
<div className="col-xl-5 col-md-6 col-12 border-t border-right">
<div className="page-account-form">
<div className="form-titel border-bottom p-3">
+1 -1
View File
@@ -57,7 +57,7 @@ export default function Subscription() {
<h2 className="text-primary pt-3">{currentSubscription?.display_name}</h2>
</div>
<div className="pt-2" style={{textAlign: 'left'}}>
<div style={{fontSize: '12px', fontWeight: 'bolder' , color: "#3E3699" }}>
<div style={{fontSize: '12px', fontWeight: 'bolder', color: "#3E3699"}}>
Next Payment: {getDateTimeFromDateString(currentSubscription?.next_payment)}
</div>
</div>
+1
View File
@@ -11,6 +11,7 @@ const siteLinks = {
comments: '/comments',
reports: '/reports',
subscription: '/subscription',
my_media: '/my-files',
subscription_success:'/subscription-success',
subscribe: '/subscribe',
onboard: '/subscription',
+1
View File
@@ -11,6 +11,7 @@ const queryKeys = {
productTemplateData: ['product_template_data'],
subscriptions: ['subscriptions'],
profile_data: ['profile_data'],
my_files: ['my_files'],
dashboard: ['dashboard'],
topBar: ['top-bar'],
+41 -3
View File
@@ -1,10 +1,9 @@
import axios from "axios"
axios.interceptors.request.use(
config => {
config.headers = {
Accept: "application/json",
// Accept: "application/json",
"Access-Control-Allow-Origin": "*",
// "Access-Control-Expose-Headers": "Access-Control-Allow-Origin",
// "Access-Control-Allow-Headers": "Origin, X-API-KEY, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Allow-Headers, Authorization, observe, enctype, Content-Length, X-Csrf-Token",
@@ -23,7 +22,16 @@ axios.interceptors.request.use(
const postAuxEnd = (path, postData, media=false) => {
const basePath = media ? process.env.REACT_APP_MAIN_API : process.env.REACT_APP_MAIN_API
return axios.post(`${basePath}${path}`, postData).then(res => {
let newPostData = {}
if(!media){
newPostData = {...postData}
}else{
newPostData = new FormData();
for (let data in postData) {
newPostData.append(data, postData[data]);
}
}
return axios.post(`${basePath}${path}`, newPostData).then(res => {
return res
}).catch(err => {
// throw new Error(err.response.data.error_message);
@@ -268,6 +276,27 @@ export const getSubscriptions = (reqData) => {
return postAuxEnd(`/panel/subscription/products`, postData, false)
}
export const getMediaFileList = (reqData) => {
let postData = {
...reqData,
}
return postAuxEnd(`/panel/account/media-files`, postData, false)
}
export const uploadFile = (reqData) => {
let postData = {
...reqData,
}
return postAuxEnd(`/upload/webfiles`, postData, true)
}
export const getReportsTopicsList = (reqData) => {
let postData = {
...reqData,
}
return postAuxEnd(`/panel/report/topics`, postData, false)
}
// FUNCTION TO GET COMMON PRACTICE
export const getCommonPractice = (reqData) => {
let postData = {
@@ -284,6 +313,15 @@ export const setExternalURL = (reqData) => {
return postAuxEnd('/panel/myproduct/external-url', postData, false)
}
// FUNCTION TO UPLOAD PROFILE IMAGE
export const uploadProfileImg = (reqData) => {
let postData = {
...reqData,
}
throw new Error('Opps')
// return postAuxEnd(`/panel/account/profile-update`, postData, true)
}
+8
View File
@@ -0,0 +1,8 @@
import React from 'react'
import MyMedia from "../component/mymedia/MyMedia";
export default function MyMediaPage() {
return (
<MyMedia />
)
}