Present message in a modal
Answered
D34dlyK1ss posted this in #help-forum
As of now I wanted to present a message/error to the user if the login credentials don't match the database. I got every piece of code sorted out aside from the actual presentation. I wanted to know how do I make the message come from the login function into the page without messing up client-side and server-side, in which I have been losing quite a lot of time enough to make me quit for a while XD
89 Replies
@D34dlyK1ss As of now I wanted to present a message/error to the user if the login credentials don't match the database. I got every piece of code sorted out aside from the actual presentation. I wanted to know how do I make the message come from the login function into the page without messing up client-side and server-side, in which I have been losing quite a lot of time enough to make me quit for a while XD
them form for entering the credentials is normally handled clientside. Then you submit a function and this function returns a value. This value can be read by your client (the form is handled clientside) and like that you can update a clientside state to display a modal
I'll be posting what I have atm
Login page
import "@/app/globals.css";
import { login } from "@/utils/userController";
export default async function LoginPage() {
return (
<div>
<div id="divLogin" className="row justify-content-md">
<h1>Login</h1>
<form action={login}>
<div id="loginUser" className="col-12">
<label htmlFor="inputUsername">Username / Email</label>
<input id="inputUsername" name="username" type="text" placeholder="Username / Email" autoComplete="on" required />
<span id="spanErrorUsername" className="spanError"></span>
</div>
<div id="loginPass" className="col-12">
<label htmlFor="inputPassword">Password</label>
<input id="inputPassword" name="password" type="password" placeholder="Password" autoComplete="on" required />
<span id="spanErrorPassword" className="spanError"></span>
</div>
<div id="loginButton" className="col-12">
<input className="btn btn-primary" type="submit" value="Login" />
</div>
</form>
<div className="col-12">
<a href="/recover">Forgot password?</a>
<br />
<a href="/register">I want to register</a>
</div>
</div>
</div>
);
}Notification Modal
import "@/app/globals.css";
import React from "react";
export default function NotificationModal(message: any) {
return (
<div className="modal fade show" id="notificationModal" tabIndex={-1} data-bs-backdrop="static" data-bs-keyboard="false" aria-modal="true" role="dialog" style={{ display: "block" }}>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div id="notificationModalBody" className="modal-body">
{message}
</div>
<div className="modal-footer border-0">
<button id="notificationModalButton" type="button" className="btn btn-primary" data-bs-dismiss="modal">
OK
</button>
</div>
</div>
</div>
</div>
);
}Login function
"use server"
export async function login(formData: FormData): Promise<any> {
try {
const [rows] = await db.execute<UserRow[]>(
`SELECT id, username, email
FROM user
WHERE (username = ? OR email = SHA2(?, 256))
AND password = SHA2(?, 256)`,
[formData.get("username"), formData.get("username"), formData.get("password")]
);
if (!rows.length) return { message: "Username/Email and Password combination does not match an existing user" };
const user = { id: rows[0].id, username: rows[0].username, email: rows[0].email };
const expires = new Date(Date.now() + 30 * 60 * 1000);
const session = await encrypt({ user, expires });
cookies().set("session", session, {
expires: expires,
httpOnly: true,
secure: true
});
} catch (err) {
console.error(err);
return { message: "Server Error" };
}
}when I was using WS, I was exposing all the code on the DevTools
but the whole code was easier to mess with even though it wasn't the correct way
so I decided to start using Next.js for the most part, and only WS for the actual gameplay (I'm doing a multiplayer game)
when I arrived on this problem, I got stuck for half a month 😅
@B33fb0n3 them form for entering the credentials is normally handled clientside. Then you submit a function and this function returns a value. This value can be read by your client (the form is handled clientside) and like that you can update a clientside state to display a modal
idk how to work with states yet
I keep getting errors like "this can't be used unless use server" or the other way around
been stuck in a loop cause of that
@D34dlyK1ss idk how to work with states yet
ok leave everything like it is and just move the actions though the
Then call the action inside your onSubmit event:
Like that the formdata should be transfered correctly. Also you can read the result from the server action.
onSubmit event and mark your form as clientside ('use client').Then call the action inside your onSubmit event:
onSubmit={(e) => {
e.preventDefault();
const result = await login(e); // read the result
}}Like that the formdata should be transfered correctly. Also you can read the result from the server action.
@B33fb0n3 ok leave everything like it is and just move the actions though the ``onSubmit`` event and mark your form as clientside (``'use client'``).
Then call the action inside your onSubmit event:
tsx
onSubmit={(e) => {
e.preventDefault();
const result = await login(e); // read the result
}}
Like that the formdata should be transfered correctly. Also you can read the result from the server action.
the login action was on another file already
@D34dlyK1ss the login action was on another file already
yea and it can stay there. The import is the same
yep
I did this
onSubmit={async (e) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
const result = await login(formData); // read the result
}}but now I want the result to trigger the modal if it's a string for example
no one in here sticks to the end
last time I got stuck for a long time because I had no people coming to help
jesus
it's been 2 weeks
@"use php"
this should be simpler than it looks
@D34dlyK1ss I did this
js
onSubmit={async (e) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
const result = await login(formData); // read the result
}}
umm, return the message from result and give a alert
explain how then
useState?
you are returning a message
a string
Just
result.message should be the messageexactly
I want to render my modal
how do I do that in the page
+ I want to distinguish what sohuld be client or server
useState
says I can't use objects in React children
when I do
{result && <NotificationModal message={result}/>}@D34dlyK1ss when I do `{result && <NotificationModal message={result}/>}`
because its of type any
change type to string
const [message, setMessage] = useState<null | string>(null)but it's defined already as null/string up there! 🤦🏻♂️
how can it lose track of this
so how do I infer the type?
as?
replace
any with stringthere's no any
@D34dlyK1ss Click to see attachment
you are setting message to {message: string;} clearly
thats why you're getting the erro
It should be
const data = await login(formData)
setMessage(data.messagein which line are you getting the error?
its 40, but highlight in code
this is throwing me off so badly 😂
Can you send your full code of notification mode again?
As a screenshot
@D34dlyK1ss Click to see attachment
I’ll check it tomorrow
damn, alright
@"use php" fixed
Answer
thank you
you made me look at things a different way 😄
not to close the modal will be a different problem
but I should get this alone
Mark solution