NGINX Upstream prematurely closed connection while reading response header from upstream, Using POST request to upload file - express

I just recently deployed an app to AWS following this tutorial: https://dev.to/rmiyazaki6499/deploying-a-production-ready-react-express-app-on-aws-62m#project-layout, and for the most part everything seemed fine however on my POST request to my express server nothing seems to happen as nothing is being sent or returned. Everything works locally as I am able to upload a file and push it to an API. If there are any suggestions on how to fix this that would be greatly appreciated.
server.js
const express = require('express');
const path = require('path');
const docparser = require('docparser-node');
const client = new docparser.Client("APIKEY");
const parserID = "cslfmvewjrvo";
const multer = require('multer');
const app = express();
//this creates the filestream needed to upload to API endpoint
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'client/public/uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer({ storage });
const fs = require('fs')
// Upload Route
app.post('/api/upload', upload.single('file'), async (req, res) => {
const file = req.file;
const stream = fs.createReadStream(`${__dirname}/../client/public/uploads/${file.filename}`);
if (file == null) {
return res.status(400).json({ msg: 'No file uploaded' });
}
try
{
let result = await client.uploadFileByStream(parserID, stream);
let docID = result.id;
console.log("This is the document ID: " + docID);
console.log("waiting for response...");
//We have to wait for a response from the API so thats what delay is for
await delay(20000);
let parsedData = await client.getResultsByDocument(parserID,docID, {format: 'object'});
let transcript = parsedData[0].final;
return res.status(200).send(transcript);
}
catch (err)
{
console.error(err)
return res.status(500).json({ msg: 'An error occurred' })
}
});
// This function delays the actions of whatever code precedes it
function delay(time) {
return new Promise(resolve => setTimeout(resolve, time));
};
app.listen(5000, () => console.log('Server Started...'));
FileUpload.js
//FileUpload.js
import React, { Fragment, useState, useEffect,useMemo } from 'react';
import axios from 'axios';
import Table from "./Table";
import Message from './Message';
import Progress from './Progress';
import '../App.css';
//This is the fileUploader Component.
const FileUpload = () => {
const [file,setFile] = useState('');
const [fileName,setFileName] = useState('Choose File');
const [data,setData] = useState([]);
const [uploadedFile, setUploadedFile] = useState({});
const [message, setMessage] = useState('');
const [uploadPercentage, setUploadPercentage] = useState(0);
const [tableData,setTableData] = useState(true);
const onChange = e => {
setFile(e.target.files[0]);
setFileName(e.target.files[0].name);
};
const onSubmit = async e => {
e.preventDefault();
const formData = new FormData();
formData.append('file', file);
try {
const res = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
setUploadPercentage(
parseInt(
Math.round((progressEvent.loaded * 100) / progressEvent.total)
)
);
}
});
setData(res.data);
console.log(setData);
setTableData(false);
// Clear percentage
setTimeout(() => setUploadPercentage(0), 10000);
const { fileName, filePath } = res.data;
setUploadedFile({ fileName, filePath });
setMessage('Transcript Uploaded');
} catch (err) {
if (err.response.status === 500) {
setMessage('There was a problem with the server');
} else {
setMessage(err.response.data.msg);
}
setUploadPercentage(0)
}
};
/*
- Columns is a simple array right now, but it will contain some logic later on. It is recommended by react-table to memoize the columns data
- Here in this example, we have grouped our columns into two headers. react-table is flexible enough to create grouped table headers
*/
const columns = useMemo(
() => [
{
// first group - Schedule
Header: "Schedule",
// First group columns
columns: [
{
Header: "Course",
accessor: "course"
},
{
Header: "Coursename",
accessor: "coursename"
},
{
Header: "Attempted",
accessor: "attempted"
},
{
Header: "Received",
accessor: "received"
}
,
{
Header: "Grade",
accessor: "grade"
}
]
}
],
[]
);
return (
<Fragment>
{message ? <Message msg={message} /> : null}
<form onSubmit={onSubmit}>
<div className='custom-file mb-4'>
<input
type='file'
className='custom-file-input'
id='customFile'
onChange={onChange}
/>
<label className='custom-file-label' htmlFor='customFile'>
{fileName}
</label>
</div>
<Progress percentage={uploadPercentage} />
<input
type='submit'
value='Upload'
className='btn btn-primary btn-block mt-4'
/>
</form>
{uploadedFile ? (
<div className='row mt-5'>
<div className='col-md-6 m-auto'>
<h3 className='text-center'>{uploadedFile.fileName}</h3>
<img style={{ width: '100%' }} src={uploadedFile.filePath} alt='' />
</div>
</div>
) : null}
{tableData ? (
<p/>
):
(
<Table columns={columns} data={data} />
)
}
</Fragment>
);
};
export default FileUpload
Nginx config
server {
server_name 52.200.122.98;
# react app & front-end files
location / {
root /home/ubuntu/KUAutoadvisor/client/build/;
try_files $uri /index.html;
}
# node api reverse proxy // the /api/ is assuming your api routes start with that i.e. www.your-site.com/api/endpoint
location /api/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_pass http://localhost:5000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_max_temp_file_size 4096m;
}
}
thank you

Related

How to run the aws-ses information of the back-end on the front-end using Axios?

I'm working on a project based on React-Native.
When a user signs up, I want to send an email verification code using AWS-SES.
Back-End entered AWS-SES information for this purpose
I want to use Axios to retrieve that information to Front-End
and send someone an email authentication number when I click [Button].
To do this, I'm asking you a question here
because I want to know how to get AWS-SES information from Back-End to Front-End and run it.
I need your help.
Thank you for reading my post.
Back-End
const { Router } = require("express");
const router = Router();
const aws = require("aws-sdk");
router.get("/mail", get_email);
exports.get_email = async (req, res) => {
try {
const testA = () => {
let ses = new aws.SES({
region: "ap-northeast-2",
});
let params = {
Destination: {
ToAddresses: ["test#gmail.com"],
},
Message: {
Body: {
Text: {
Data: "TEST MESSAGE",
},
},
Subject: { Data: "TEST" },
},
Source: "test#gmail.com",
};
return ses.sendEmail(params).promise();
};
return res.status(200).json({ success: true, testA });
} catch (e) {
console.log(e);
}
};
Front-End
import React, { useState, useEffect } from "react";
import axios from "axios";
const [test, setTest] = useState([]);
useEffect(() => {
getTest();
}, []);
const getTest = async () => {
await axios.get("/mail").then((res) => {
if (res.data) {
setTest(res.data.testA);
}
});
};
return (
<div>
<div onClick={()=>{
getTest();
console.log("Test AWS-SES : ", test);
}}>
Test
</div>
</div>
);
Result
Test AWS-SES : undefined

Vue 3, Socket IO - not listening to event

For server side I have following code:
const path = require("path");
const http = require("http");
const express = require("express");
const {instrument} = require('#socket.io/admin-ui')
const app = express()
const server = http.createServer(app)
const io = require("socket.io")(server, {
cors: {
origin: ["https://admin.socket.io", "http://localhost:3001"],
credentials: true
},
});
instrument(io, { auth: false });
server.listen(3000, () =>
console.log('connected')
)
io.on('connection', socket => {
console.log("user connected");
socket.on("join", function (room) {
console.log(room);
socket.join(room);
});
socket.on('newOrder', function (data) {
socket.emit('this', data)
console.log(data);
})
socket.on("thisNew", function (data) {
console.log('this new');
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
})
and in the Vue (client side) I have following:
import VueSocketIO from 'vue-3-socket.io'
import SocketIO from 'socket.io-client'
export const useSocketIO = () => {
const socket = new VueSocketIO({
debug: true,
connection: SocketIO('http://localhost:3000')
})
return {
socket,
}
}
And in the component:
<script setup>
import { useSocketIO } from "#/services/socketio"
const { socket } = useSocketIO()
onMounted(async () =>
{
await socket.io.emit('join', 'servant')
socket.io.on('this', () =>
{
console.log('event this fired')
})
})
</script>
Event this is emitted from the server, but nothing is happening on the client side. What am I doing wrong here?

Secure random number generation is not supported by this browser

I am trying to establish a peer-to-peer video connection between a web frontend and a react-native android smart tv app. I want to display the user's webcam video on the smart tv. I am using an express server for signaling:
const app = require("express")();
const server = require("http").createServer(app);
const cors = require("cors");
const io = require("socket.io")(server, {
cors: {
origin: "*",
methods: [ "GET", "POST" ]
}
});
app.use(cors());
const PORT = process.env.PORT || 8082;
//here we define the behaviour of the API Endpoints
app.get('/', (req, res) => {
res.send('Runnin');
});
app.post('/',(req,res) => {
const body = req.body;
res.send(body);
});
io.on("connection", (socket) => {
socket.emit("me", socket.id);
console.log(socket.id);
socket.on("disconnect", () => {
socket.broadcast.emit("callEnded")
});
socket.on("callUser", ({ userToCall, signalData, from, name }) => {
io.to(userToCall).emit("callUser", { signal: signalData, from, name });
});
socket.on("answerCall", (data) => {
io.to(data.to).emit("callAccepted", data.signal)
});
});
server.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
The signaling is working but as I am trying to display the video the following error is displayed:
[Link to screenshot of the error][1]
Code of the react-native Callscreen component:
import React, { useEffect, useState, useCallback, useContext } from 'react';
import { View, StyleSheet, Alert, Button, Text } from 'react-native';
import { RTCView } from 'react-native-webrtc';
import { SocketContext } from './Context';
import Callnotification from './Callnotifcation';
function CallScreen(props) {
const { callAccepted, userVideo, callEnded, me } = useContext(SocketContext);
return (
<>
{callAccepted && !callEnded && (
<View style={styles.root}>
<View style={[styles.videos, styles.remoteVideos]}>
<Text>Video of the caller</Text>
<RTCView streamURL={JSON.stringify(userVideo)} style={styles.remoteVideo} />
</View>
</View>
)
}
<View style={styles.root}>
<Callnotification />
<Text>{JSON.stringify(me)}</Text>
</View>
</>
);
}
Code of the Context.js connecting the react-native app to the signaling server:
import React, { createContext, useState, useRef, useEffect } from 'react';
import { io } from 'socket.io-client';
import Peer from 'simple-peer';
const SocketContext = createContext();
const socket = io('http://10.0.2.2:8082'); // use this to access via android emulator
//const socket = io('http://192.168.178.106:8082'); //use this to access via SmartTv Fire Tv Stick
const ContextProvider = ({ children }) => {
const [callAccepted, setCallAccepted] = useState(false);
const [callEnded, setCallEnded] = useState(false);
const [stream, setStream] = useState();
const [name, setName] = useState('');
const [call, setCall] = useState({});
const [me, setMe] = useState('');
const userVideo = useRef();
const connectionRef = useRef();
useEffect(() => {
socket.on('me', (id) => setMe(id));
socket.on('callUser', ({ from, name: callerName, signal }) => {
setCall({ isReceivingCall: true, from, name: callerName, signal });
});
}, []);
const answerCall = () => {
setCallAccepted(true);
const peer = new Peer({ initiator: false, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('answerCall', { signal: data, to: call.from });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
peer.signal(call.signal);
connectionRef.current = peer;
};
/* const callUser = (id) => {
const peer = new Peer({ initiator: true, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('callUser', { userToCall: id, signalData: data, from: me, name });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
socket.on('callAccepted', (signal) => {
setCallAccepted(true);
peer.signal(signal);
});
connectionRef.current = peer;
};*/
const leaveCall = () => {
setCallEnded(true);
connectionRef.current.destroy();
};
return (
<SocketContext.Provider value={{
call,
callAccepted,
setCallAccepted,
userVideo,
stream,
name,
setName,
callEnded,
me,
leaveCall,
answerCall,
}}
>
{children}
</SocketContext.Provider>
);
};
export { ContextProvider, SocketContext };
Code of the Context.js connecting the web react frontend to the signaling server:
import React, { createContext, useState, useRef, useEffect } from 'react';
import { io } from 'socket.io-client';
import Peer from 'simple-peer';
const SocketContext = createContext();
// const socket = io('http://localhost:5000');
const socket = io('http://localhost:8082');
const ContextProvider = ({ children }) => {
const [callAccepted, setCallAccepted] = useState(false);
const [callEnded, setCallEnded] = useState(false);
const [stream, setStream] = useState();
const [name, setName] = useState('');
const [call, setCall] = useState({});
const [me, setMe] = useState('');
const myVideo = useRef();
const userVideo = useRef();
const connectionRef = useRef();
useEffect(() => {
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then((currentStream) => {
setStream(currentStream);
myVideo.current.srcObject = currentStream;
});
socket.on('me', (id) => setMe(id));
socket.on('callUser', ({ from, name: callerName, signal }) => {
setCall({ isReceivingCall: true, from, name: callerName, signal });
});
}, []);
const answerCall = () => {
setCallAccepted(true);
const peer = new Peer({ initiator: false, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('answerCall', { signal: data, to: call.from });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
peer.signal(call.signal);
connectionRef.current = peer;
};
const callUser = (id) => {
const peer = new Peer({ initiator: true, trickle: false, stream });
peer.on('signal', (data) => {
socket.emit('callUser', { userToCall: id, signalData: data, from: me, name });
});
peer.on('stream', (currentStream) => {
userVideo.current.srcObject = currentStream;
});
socket.on('callAccepted', (signal) => {
setCallAccepted(true);
peer.signal(signal);
});
connectionRef.current = peer;
};
const leaveCall = () => {
setCallEnded(true);
connectionRef.current.destroy();
window.location.reload();
};
return (
<SocketContext.Provider value={{
call,
callAccepted,
myVideo,
userVideo,
stream,
name,
setName,
callEnded,
me,
callUser,
leaveCall,
answerCall,
}}
>
{children}
</SocketContext.Provider>
);
};
export { ContextProvider, SocketContext };
In my opinion the error lies in the RTCView of the Callscreen but i have no idea how to fix it. Your help is very much appreciated!
Thank you very much!
[1]: https://i.stack.imgur.com/YBh9P.jpg
The library that you are using is probably using the SubtleCrypto.generateKey function to generate shared secrets. This API is "only available in a secure context", which means that it can only be used if the page is served over HTTPS.
Serve your page over HTTPS, and the error should go away.

MERN app doesn't function correctly on heroku netlify but works properly on localhost

I'm having a hard time trying to fix my login page
I've provided a very short youtube video on what is the problem that I encountered.
Youtube Link: https://youtu.be/lpyJo6tmiRs
It works properly on localhost but breaks when I deploy to herkou & netlify.
Register function also works properly
I provided everything here and also hidden some important info like mongodb user and passwords.
Website Link
https://incomparable-speculoos-abdd5f.netlify.app/
Login Page
import React, { useState, useEffect } from 'react'
import { useNavigate } from "react-router-dom"
import Axios from 'axios'
import './login.css'
import Register from '../register/register'
const Login = () => {
const navigate = useNavigate();
const [style, setStyle] = useState('hidden')
const [border, setBorder] = useState(false)
const [email, setEmail] = useState('')
const [password, setPass] = useState('')
const [errMsg, setErr] = useState('')
Axios.defaults.withCredentials = true;
const handleEmail = (e) => {
setEmail(e.target.value)
}
const handlePassword = (e) => {
setPass(e.target.value)
}
const show = () => [
setStyle('registerParent')
]
const hide = () => {
setStyle('hidden')
}
const reloadA = () => {
window.location.reload(false);
}
// FUNCTION WHEN LOGIN IS CLICKED
const login = () => {
Axios.post('https://votereact-app.herokuapp.com/login',
{email: email,
password: password,
}).then((response) => {
// CHECKS IF THERE IS A MESSAGE FROM THE BACKEND (MEANS THERE IS A PROBLEM IN THE LOGIN)
if (response.data.message) {
setErr(response.data.message)
setBorder(true)
} else {
// NAVIGATES TO /home ROUTE OF THERE IS NO MESSAGE (/route redirects to privateRoute)
setErr("Logged in")
setBorder(false)
navigate('/home', {replace: true})
}
})
}
return (
<>
<div className="loginParent">
<div className="loginContainer">
<h1 className="vote-login">VoteReact</h1>
<div className="loginBox">
<div className="inputs-parent">
<input type="text" style={{border: border ? '1px solid #e2252b' : '1px solid #1B74E4'}} placeholder="Email" className="email-input" onChange={handleEmail}></input>
<input type="password" style={{border: border ? '1px solid #e2252b' : '1px solid #1B74E4'}}placeholder="Password" className="password-input" onChange={handlePassword}></input>
<p className="errMsg">{errMsg}</p>
</div>
<button className="loginButton" onClick={login}>Log in</button> {/* LOGIN BUTTON */}
<p className="forgot">Forgot Password?</p>
<button className="signup" onClick={show}>Sign up</button>
</div>
</div>
</div>
<Register styleName={style.toString()} close={() => hide()} load={() =>reloadA()}/>
</>
)
}
export default Login
BACK END CODE
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose")
const app = express();
const bcrypt = require("bcryptjs")
const saltRounds = 10;
const bodyParser = require("body-parser")
const cookieParser = require("cookie-parser")
const session = require("express-session")
const voterModel = require('./modules/voters.js')
const presidentModel = require('./modules/president.js')
const viceModel = require('./modules/vice.js')
const treasurerModel = require('./modules/treasurer.js')
app.use(express.json());
require('dotenv').config();
app.use(cors({credentials: true, origin: 'https://incomparable-speculoos-abdd5f.netlify.app'}));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }))
app.use(session({
key: "userId",
secret: "hidden",
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 60000
}
}))
mongoose.connect("hidden",
{
useNewUrlParser: true,
useUnifiedTopology: true
}
)
// GET THE SESSION AND CHECK IF IT DOES EXIST OR NO
//IF YES THEN LOGGEDIN: TRUE ELSE, FALSE
// --- HERE IS WHERE I ENCOUNTER PROBLEM, IT SHOULD RETURN TRUE AFTER I LOG IN BUT STILL RETURNS FALSE ---
app.get('/login', async (req, res) => {
if (req.session.voter) {
res.send({loggedIn: true})
} else {
res.send({loggedIn: false})
}
})
app.post('/login', async (req, res) => {
const email = req.body.email;
const password = req.body.password;
// CHECKS IF USER EMAIL EXISTS
voterModel.find({email: email}, {"email":1}, async (err, result) => {
if (err) {
console.log(err)
} else {
if(result.length > 0) {
// COMPARES PASSWORD IF IT IS CORRECT
const user = await voterModel.findOne({email: email})
const pass = await user.comparePassword(password)
if (pass) {
// SAVE THE SESSION IF PASS IS CORRECT
req.session.voter = result
var oneWeek = 60 * 60 * 24; //1 week
req.session.voter.expires = new Date(Date.now() + oneWeek);
req.session.voter.maxAge = oneWeek;
console.log(req.session.voter)
res.send(result)
} else {
console.log("NOT LOGGED IN")
res.send({ message: 'Invalid email or password!'})
}
} else {
console.log("NOT LOGGED IN")
res.send({ message: 'Invalid email or password!'})
}
}
})
})
app.post('/register', async (req, res) => {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
// HASING PASSWORD
bcrypt.hash(password, saltRounds, async (err, hash) => {
if (err) {
console.log(err)
}
// INSERTING VALUES
const voters = await voterModel({email: email, username: username, password: hash, status: false})
// CHECKS IF EMAIL IS IN USE
const isNewEmail = await voterModel.isThisEmailInUse(email)
if (!isNewEmail) return res.send({ message: 'This email is already taken!'})
// SAVES THE INSERT DATA FOR VOTERS
await voters.save()
res.send({success: true})
})
})
app.post('/logout', (req, res) => {
if(req.session.voter) {
req.session.voter = null;
req.session.destroy();
}
})
const PORT = process.env.PORT || 3001
app.listen(PORT, () => {
console.log('Running on port successfuly')
})
Private Route to Home
import React, { useState, useEffect } from 'react'
import { useNavigate } from "react-router-dom"
import Axios from 'axios'
import Home from "./home/home.js"
const PrivateRoute = () => {
Axios.defaults.withCredentials = true;
const navigate = useNavigate();
const [loggedIn, setLoggedIn] = useState(false);
useEffect(()=> {
// GET DATA FROM axios.get(/login) on backend
Axios.get("https://votereact-app.herokuapp.com/login").then((response) => {
if (response.data.loggedIn === true) {
setLoggedIn(true);
console.log(response)
} else {
navigate("/" , {replace: true})
console.log(response)
}
})
},[])
// WHILE CHECKING IF Logged in or not
if (!loggedIn) {
return (
<>
Loading...
</>
)
}
// Redirects to real home page if user is logged in
return (
<>
<Home/>
</>
)
}
export default PrivateRoute

Application error: a client-side exception has occurred (see the browser console for more information) .NEXT JS

In my extjs application , authorization works on the local host , but the page server gives an error : Application error: a client-side exception has occurred (see the browser console for more information) . They want a login, password are saved to the database, when logging in, a redirect to a page protected via axios is successfully performed, and there is an error there.
The cook's locale is saved correctly, but apparently cannot be counted from there.
I added a header (Access-Control-Allow-Origin) to the request, it didn't help.
My service :
import axios, {AxiosError} from "axios";
import { Router, useRouter } from "next/router";
import { useQuery } from "react-query";
const host = process.env.HOST || 'http://localhost:3000'
// axios instance
export const apiClient = axios.create({
baseURL: host + "/api",
withCredentials: true,
headers: {
"Content-type": "application/json"
},
});
export type Admin = {
id: string
login: string
}
export type RedirectError = {
redirectUrl: string
}
export const getSession = async () => {
const response = await apiClient.get<Admin>('getSession')
return response.data
}
export const useSession = () => {
const router = useRouter()
const { isLoading, error, data, isSuccess } = useQuery<Admin, AxiosError<RedirectError>>('sid', getSession)
if (error) router.push(error.response.data.redirectUrl)
return { isLoading, error, data, isSuccess }
}
My api/getSession:
import type { NextApiRequest, NextApiResponse } from 'next'
import checkSession from '../../src/services/checkCookie'
export default async function getSession(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'GET') {
try {
const sid = req.cookies['sid']
const admin = await checkSession(sid)
if (admin) {
const { id, login } = admin.admin
return res.send({ id, login })
}
const host = process.env.NODE_ENV === 'production' ? process.env.HOST : 'http://localhost:3000'
return res.status(401).send({ redirectUrl: host + '/admin/login' })
} catch (error) {
console.error(error)
res.status(500).send({ message: "" })
}
} else {
res.status(404).send({ message: "" })
}
}
checkSession in getSession api :
export default async function checkSession (token: string) {
// const token = req.cookies['sid']
if (typeof window === 'undefined' && token) {
const unsign = (await import('./signature')).unsign
const sessionToken = unsign(token, process.env.SECRET!)
if (sessionToken && typeof sessionToken === 'string') {
const db = (await import('../../prisma')).default
const session = await db.session.findUnique({ where: { sessionToken },
include: { admin: true } })
if (session) {
return { admin: session.admin }
}
}
}
}
Page with axios
import { NextPage } from "next"
import TableService from "../src/component/TableService"
import AdminLayout from "../src/component/admin/AdminLayout"
import { Admin, getSession, RedirectError, useSession } from "../src/services/apiClient"
import { useRouter } from "next/router"
import { CircularProgress } from "#mui/material"
const AdminTable: NextPage = () => {
const router = useRouter()
const {isLoading, error, data, isSuccess } = useSession()
if (isLoading) return <CircularProgress />
return (
<>
{data && <div>{data.login}</div>}
{isSuccess &&
<AdminLayout title="">
<TableService />
</AdminLayout>
}
{isLoading && <p>Loading..</p>}
{error && <p>Error occurred!</p>}
</>
)
}
export default AdminTable