Commit ba6bd4ec authored by 健杭 徐's avatar 健杭 徐
Browse files

main.go func DeleteRoom

parent 1d85ac6b
...@@ -2,7 +2,10 @@ module chatroom ...@@ -2,7 +2,10 @@ module chatroom
go 1.24.3 go 1.24.3
require github.com/gin-gonic/gin v1.10.1 require (
github.com/gin-gonic/gin v1.10.1
github.com/lib/pq v1.10.9
)
require ( require (
github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic v1.11.6 // indirect
......
...@@ -36,6 +36,8 @@ github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY ...@@ -36,6 +36,8 @@ github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
......
...@@ -4,8 +4,11 @@ import ( ...@@ -4,8 +4,11 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
"log" "log"
"net/http"
"strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
_ "github.com/lib/pq"
) )
const ( const (
...@@ -26,10 +29,11 @@ type Message struct { ...@@ -26,10 +29,11 @@ type Message struct {
} }
type RoomPreviewInfo struct { type RoomPreviewInfo struct {
RoomId int `json:"room_id"` RoomId int `json:"roomId"`
RoomName string `json:"room_name"` RoomName string `json:"roomName"`
LastMessage string `json:"last_message"` LastSender sql.NullString `json:"lastSender"`
LastMessageTime string `json:"last_message_time"` LastContent sql.NullString `json:"lastContent"`
LastTime sql.NullTime `json:"lastTime"`
} }
type Response struct { type Response struct {
...@@ -83,8 +87,15 @@ func main() { ...@@ -83,8 +87,15 @@ func main() {
router := gin.Default() router := gin.Default()
router.Use(func(c *gin.Context) { router.Use(func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST") c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}) })
router.POST("/room/add", AddNewRoom) router.POST("/room/add", AddNewRoom)
...@@ -113,8 +124,6 @@ func AddNewRoom(c *gin.Context) { ...@@ -113,8 +124,6 @@ func AddNewRoom(c *gin.Context) {
} }
room.RoomId = roomId room.RoomId = roomId
room.LastMessage = ""
room.LastMessageTime = ""
c.JSON(200, RoomAddRes{ c.JSON(200, RoomAddRes{
RoomId: room.RoomId, RoomId: room.RoomId,
}) })
...@@ -122,42 +131,125 @@ func AddNewRoom(c *gin.Context) { ...@@ -122,42 +131,125 @@ func AddNewRoom(c *gin.Context) {
} }
func GetRoomList(c *gin.Context) { func GetRoomList(c *gin.Context) {
var total int
roomCountQuery := "SELECT COUNT(*) FROM rooms"
err := db.QueryRow(roomCountQuery).Scan(&total)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
"msg": "总数统计失败:" + err.Error(),
})
return
}
query := `
SELECT room_id, room_name, last_sender, last_content, last_time
FROM rooms
ORDER BY last_time DESC NULLS LAST
`
args := []interface{}{}
rows, err := db.Query(query, args...)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
"msg": "Falie while serch:" + err.Error(),
})
return
}
defer rows.Close()
var roomList []RoomPreviewInfo
for rows.Next() {
var roomItem RoomPreviewInfo
if err := rows.Scan(
&roomItem.RoomId,
&roomItem.RoomName,
&roomItem.LastSender,
&roomItem.LastContent,
&roomItem.LastTime,
); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
"msg": "Faile while parsing" + err.Error(),
})
return
}
roomList = append(roomList, roomItem)
}
c.JSON(http.StatusOK, Response{
Code: 0,
Msg: "Success",
Data: roomList,
})
} }
func DeleteRoom(c *gin.Context) { func DeleteRoom(c *gin.Context) {
roomId, err := strconv.Atoi((c.Query("roomTd")))
if err != nil || roomId <= 0 {
c.JSON(http.StatusOK, Response{Code: 400, Msg: "Invalid ID"})
return
}
result, err := db.Exec("DELETE FROM rooms WHERE roomId = $1", roomId)
if err != nil {
c.JSON(http.StatusOK, Response{Code: 500, Msg: err.Error()})
return
}
rowsAffected, _ := result.RowsAffected()
if rowsAffected == 0 {
c.JSON(http.StatusOK, Response{Code: 400, Msg: "Room not found"})
return
}
c.JSON(http.StatusOK, Response{
Code: 0,
Msg: "Room deleted",
Data: nil,
})
} }
func AddMessage(c *gin.Context) { func AddMessage(c *gin.Context) {
// 处理添加消息的逻辑 var message struct {
var message Message RoomId int `json:"roomId"`
ProfileId int `json:"profile_id"`
Sender string `json:"sender"`
Content string `json:"content"`
}
if err := c.ShouldBindJSON(&message); err != nil { if err := c.ShouldBindJSON(&message); err != nil {
c.JSON(400, Response{Code: 400, Msg: "Invalid input", Data: nil}) c.JSON(http.StatusBadRequest, Response{Code: 400, Msg: "Invalid input: " + err.Error(), Data: nil})
return return
} }
query := `
INSERT INTO messages (room_id, profile_id, sender, content)
VALUES ($1, $2, $3, $4)
RETURNING message_id
`
var messageId int var messageId int
err := db.QueryRow( err := db.QueryRow(query, message.RoomId, message.ProfileId, message.Sender, message.Content).Scan(&messageId)
"INSERT INTO messages (roomId, profile_id, sender, content, timestamp) VALUES ($1, $2, NOW()) RETURNING message_id", if err != nil {
message.RoomId, message.Profile_id, message.Sender, message.Content, c.JSON(http.StatusInternalServerError, Response{Code: 500, Msg: "Failed to add message: " + err.Error(), Data: nil})
).Scan(&messageId) return
}
_, err = db.Exec( _, err = db.Exec(
"UPDATE rooms SET last_sender = $1, last_content = $2, last_time = NOW() WHERE room_id = $3", "UPDATE rooms SET last_sender = $1, last_content = $2, last_time = NOW() WHERE room_id = $3",
message.Sender, message.Content, message.RoomId, message.Sender, message.Content, message.RoomId,
) )
if err != nil { if err != nil {
c.JSON(500, Response{Code: 500, Msg: "Failed to add message", Data: nil}) log.Printf("Failed to update room preview: %v", err)
return
} }
message.MessageId = messageId c.JSON(http.StatusOK, Response{
c.JSON(200, Response{
Code: 0, Code: 0,
Msg: "Message added successfully", Msg: "Message added successfully",
Data: message, Data: gin.H{"messageId": messageId},
}) })
log.Printf("New message added: %+v", message) log.Printf("New message with ID %d added to room %d", messageId, message.RoomId)
} }
func GetMessageList(c *gin.Context) { func GetMessageList(c *gin.Context) {
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
"dependencies": { "dependencies": {
"next": "15.3.3", "next": "15.3.3",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0" "react-dom": "^19.0.0",
"react-icons": "^5.5.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20", "@types/node": "^20",
...@@ -837,6 +838,15 @@ ...@@ -837,6 +838,15 @@
"react": "^19.1.0" "react": "^19.1.0"
} }
}, },
"node_modules/react-icons": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
"license": "MIT",
"peerDependencies": {
"react": "*"
}
},
"node_modules/scheduler": { "node_modules/scheduler": {
"version": "0.26.0", "version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
......
...@@ -9,14 +9,15 @@ ...@@ -9,14 +9,15 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"next": "15.3.3",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"next": "15.3.3" "react-icons": "^5.5.0"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19" "@types/react-dom": "^19",
"typescript": "^5"
} }
} }
...@@ -138,4 +138,9 @@ h1, h2, h3, h4, h5, h6, ...@@ -138,4 +138,9 @@ h1, h2, h3, h4, h5, h6,
transform: translate(3px, 3px); transform: translate(3px, 3px);
box-shadow: 0px 0px var(--main-color); box-shadow: 0px 0px var(--main-color);
} }
}
.root {
display: flex;
position: relative;
} }
\ No newline at end of file
import React from 'react'; 'use client';
import ChatRoom from "./pages/ChatRoom/ChatRoom";
import React, { useState } from 'react';
import { ChatRoom } from "./pages/ChatRoom/ChatRoom";
import { SetName } from './pages/SetName/SetName';
import "./globals.css"; import "./globals.css";
export default function Page() { export default function Page() {
const [userName, setUserName] = useState('');
const handleLogin = (name: string) => {
setUserName(name);
};
return ( return (
<div> <div className='root'>
<ChatRoom /> {!userName ? (
<SetName onLogin={handleLogin} />
) : (
<ChatRoom userName={userName} />
)}
</div> </div>
); );
} }
\ No newline at end of file
.chat-room { .chat-room {
display: flex; display: flex;
position: relative; position: fixed;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
box-sizing: border-box; box-sizing: border-box;
......
...@@ -33,18 +33,7 @@ interface MessageProps { ...@@ -33,18 +33,7 @@ interface MessageProps {
}>; }>;
} }
let RoomName: RoomEntryProps[] = [ let RoomName: RoomEntryProps[] = []
{ roomId: 1, roomName: "General", lastSender: "Alice", lastContent: "Hello!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", lastTime: "" },
{ roomId: 2, roomName: "Sports", lastSender: "Bob", lastContent: "Did you watch the game last night?", lastTime: "" },
{ roomId: 3, roomName: "Movies", lastSender: "Charlie", lastContent: "I loved the new movie!", lastTime: "" },
{ roomId: 4, roomName: "Music", lastSender: "David] ", lastContent: "Have you heard the latest album?", lastTime: "" },
]
let RoomRightNow: MessageProps = { roomId:0, roomName:"", messages:[{profile: 0, sender: "", content: "", time: ""}]}; // Initialize with default values
if (RoomName.length > 0) {
RoomRightNow.roomId = RoomName[0].roomId; // 默认选中第一个房间
RoomRightNow.roomName = RoomName[0].roomName;
}
function RoomEntry ({rooms, onRoomClick} : {rooms: RoomEntryProps[], onRoomClick: (roomId: number, roomName: string) => void}) { function RoomEntry ({rooms, onRoomClick} : {rooms: RoomEntryProps[], onRoomClick: (roomId: number, roomName: string) => void}) {
return ( return (
...@@ -63,8 +52,8 @@ function RoomEntry ({rooms, onRoomClick} : {rooms: RoomEntryProps[], onRoomClick ...@@ -63,8 +52,8 @@ function RoomEntry ({rooms, onRoomClick} : {rooms: RoomEntryProps[], onRoomClick
<img src={RoomProfile} alt="Avatar" className="avatar" /> <img src={RoomProfile} alt="Avatar" className="avatar" />
<div className="chat-info"> <div className="chat-info">
<h3>{room.roomName}</h3> <h3>{room.roomName}</h3>
<span className="chat-message">{room.lastContent}</span> <span className="chat-message">{room.lastContent && room.lastContent.Valid ? room.lastContent.String : ''}</span>
<span className="chat-time"></span> <span className="chat-time">{room.lastTime && room.lastTime.Valid ? room.lastTime.String : ''}</span>
</div> </div>
</div> </div>
))} ))}
...@@ -74,14 +63,6 @@ function RoomEntry ({rooms, onRoomClick} : {rooms: RoomEntryProps[], onRoomClick ...@@ -74,14 +63,6 @@ function RoomEntry ({rooms, onRoomClick} : {rooms: RoomEntryProps[], onRoomClick
// Button From Uiverse.io by njesenberger // Button From Uiverse.io by njesenberger
} }
function handleRoomClick(roomId: number, roomName: string) {
RoomRightNow.roomId = roomId;
RoomRightNow.roomName = roomName;
// here unsuccessfully
// try to update the last message info
}
function InputRoomNameArea() { function InputRoomNameArea() {
// This component is used to input the new room name // This component is used to input the new room name
return ( return (
...@@ -102,9 +83,7 @@ function InputRoomNameArea() { ...@@ -102,9 +83,7 @@ function InputRoomNameArea() {
}} }}
/> />
<div className="button-container"> <div className="button-container">
<button className="create-button" onClick={() =>{ <button className="create-button" onClick={addNewRoom}>Submit</button>
addNewRoom();
}}>Submit</button>
<button className="cancel-button" onClick={closeOpenDiv}>Cancel</button> <button className="cancel-button" onClick={closeOpenDiv}>Cancel</button>
</div> </div>
</div> </div>
...@@ -114,6 +93,7 @@ function InputRoomNameArea() { ...@@ -114,6 +93,7 @@ function InputRoomNameArea() {
async function addNewRoom() { async function addNewRoom() {
const RoomNameInput = (document.getElementsByClassName("RoomNameInput")[0] as HTMLInputElement).value; const RoomNameInput = (document.getElementsByClassName("RoomNameInput")[0] as HTMLInputElement).value;
debugger;
if (RoomNameInput === "") { if (RoomNameInput === "") {
alert("Please enter a room name."); alert("Please enter a room name.");
return; return;
...@@ -123,10 +103,14 @@ async function addNewRoom() { ...@@ -123,10 +103,14 @@ async function addNewRoom() {
const response = await fetch ("http://localhost:8080/room/add", { const response = await fetch ("http://localhost:8080/room/add", {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ room_name: RoomNameInput }) body: JSON.stringify({ roomName: RoomNameInput })
}) })
const result = await response.json(); const result = await response.json();
if (result.Code === 500) {
alert("Faile to add new room");
return
}
const NewRoomId = result.room_id; const NewRoomId = result.room_id;
RoomName.push({ RoomName.push({
roomId: NewRoomId, roomId: NewRoomId,
...@@ -139,7 +123,7 @@ async function addNewRoom() { ...@@ -139,7 +123,7 @@ async function addNewRoom() {
const chatList = document.getElementsByClassName("chat-list")[0]; const chatList = document.getElementsByClassName("chat-list")[0];
const newRoom = document.createElement("div"); const newRoom = document.createElement("div");
newRoom.className = "chat-item"; newRoom.className = "chat-item";
newRoom.setAttribute("key", NewRoomId.toString()); newRoom.setAttribute("key", NewRoomId);
newRoom.innerHTML = ` newRoom.innerHTML = `
<img src="${RoomProfile}" alt="Avatar" class="avatar" /> <img src="${RoomProfile}" alt="Avatar" class="avatar" />
<div class="chat-info" > <div class="chat-info" >
...@@ -155,6 +139,8 @@ async function addNewRoom() { ...@@ -155,6 +139,8 @@ async function addNewRoom() {
} }
closeOpenDiv(); closeOpenDiv();
// 加一个刷新的函数
// RoomEntry(); // RoomEntry();
} }
...@@ -173,7 +159,7 @@ function closeOpenDiv() { ...@@ -173,7 +159,7 @@ function closeOpenDiv() {
(document.getElementsByClassName("RoomNameInput")[0] as HTMLInputElement).value = ''; (document.getElementsByClassName("RoomNameInput")[0] as HTMLInputElement).value = '';
} }
function MessageItem (props: MessageProps) { function MessageItem (props: MessageProps & { userName: string }) {
if (props.roomId === 0) { if (props.roomId === 0) {
return <div className="message-item">Please select a room to chat.</div>; return <div className="message-item">Please select a room to chat.</div>;
} }
...@@ -201,10 +187,10 @@ function MessageItem (props: MessageProps) { ...@@ -201,10 +187,10 @@ function MessageItem (props: MessageProps) {
<input type="text" placeholder="Type a message..." className="Inputarea" onKeyUpCapture={ <input type="text" placeholder="Type a message..." className="Inputarea" onKeyUpCapture={
(e: React.KeyboardEvent<HTMLInputElement>) => { (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
addNewComment(props.roomId, "蔡徐坤", (e.target as HTMLInputElement).value); addNewComment(props.roomId, props.userName, (document.getElementsByClassName("Inputarea")[0] as HTMLInputElement).value);
} }
}}/> }}/>
<button className="send-button" onClick={() => addNewComment(props.roomId, "蔡徐坤", (document.getElementsByClassName("Inputarea")[0] as HTMLInputElement).value)}> <button className="send-button" onClick={() => addNewComment(props.roomId, props.userName, (document.getElementsByClassName("Inputarea")[0] as HTMLInputElement).value)}>
<div className="svg-wrapper-1"> <div className="svg-wrapper-1">
<div className="svg-wrapper"> <div className="svg-wrapper">
<svg <svg
...@@ -285,7 +271,7 @@ function addNewComment(roomId: number, sender: string, content: string) { ...@@ -285,7 +271,7 @@ function addNewComment(roomId: number, sender: string, content: string) {
} }
} }
export default function ChatRoom() { export function ChatRoom({ userName }: { userName: string }) {
const [rooms, setRooms] = useState<RoomEntryProps[]>([]); const [rooms, setRooms] = useState<RoomEntryProps[]>([]);
const [currentRoom, setCurrentRoom] = useState<MessageProps | null>(null); const [currentRoom, setCurrentRoom] = useState<MessageProps | null>(null);
...@@ -324,23 +310,45 @@ export default function ChatRoom() { ...@@ -324,23 +310,45 @@ export default function ChatRoom() {
} }
}, [currentRoom?.roomId]); }, [currentRoom?.roomId]);
const handleRoomClick = (roomId: number, roomName: string) => { const handleRoomClick = async (roomId: number, roomName: string) => {
setCurrentRoom({ setCurrentRoom({
roomId: roomId, roomId: roomId,
roomName: roomName, roomName: roomName,
messages: [] messages: []
}); });
try {
const response = await fetch(`http://localhost:8080/room/message/list?roomId=${roomId}`)
const result = await response.json();
if (result.code === 0) {
setCurrentRoom({
roomId: roomId,
roomName: roomName,
messages: result.data || []
});
} else {
alert(`Error fetching messages: ${result.msg}`);
setCurrentRoom({
roomId: roomId,
roomName: roomName,
messages: []
});
}
} catch (error){
console.error("Error fetching messages:", error);
alert("Failed to fetch messages. See console for details.");
}
} }
return ( return (
<div className="chat-room"> <div className="chat-room">
<RoomEntry rooms={rooms} onRoomClick={handleRoomClick}/> <RoomEntry rooms={rooms} onRoomClick={handleRoomClick}/>
<MessageItem <MessageItem
roomId={RoomRightNow.roomId} roomId={currentRoom?.roomId || 0}
roomName={RoomRightNow.roomName} roomName={currentRoom?.roomName || ""}
messages={[ messages={currentRoom?.messages || []}
{ profile: 2, sender: "Alice", content: RoomRightNow.roomName, time: "Right Now" } userName={userName}
]}
/> />
<InputRoomNameArea /> <InputRoomNameArea />
</div> </div>
......
*
{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
.SetName-Body
{
z-index: 2000;
display: flex;
position: absolute;
justify-content: center;
align-items: center;
min-height: 100vh;
width: 100vw;
background-size: cover;
background: url('../../public/SetbackGround.jpg') no-repeat center;
}
.login-box
{
position: relative;
width: 400px;
height: 450px;
background-color: transparent;
border: 2px solid rgba(255, 255 , 255, .5);
border-radius: 20px;
display: flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(15px);
}
h2
{
font-size: 2em;
color: white;
text-align: center;
}
.input-box
{
position: relative;
width: 310px;
margin: 30px 0;
border-bottom: 2px solid white;
}
.input-box label
{
position: absolute;
top: 50%;
left: 5px;
transform: translateY(-50%);
font-size: 1em;
color: white;
pointer-events: none;
transition: .5s;
}
.input-box input:focus~label,
.input-box input:valid~label
{
top: -5px;
}
.input-box input
{
width: 100%;
height: 50px;
border: none;
outline: none;
background-color: transparent;
color: white;
font-size: 1em;
padding: 0 35px 0 5px;
}
.input-box .icon
{
position: absolute;
right: 8px;
color: white;
font-size: .9em;
line-height: 57px;
}
.SetName-button
{
outline: none;
border: none;
width: 100%;
height: 50px;
background-color: white;
border-radius: 40px;
cursor: pointer;
color: black;
font-size: 1em;
font-weight: bold;
}
.SetName-button:hover
{
background-color: lightgray;
}
'use client';
import "./SetName.css"
import { MdPerson } from "react-icons/md";
import { useRouter } from "next/compat/router";
import { useState } from "react";
export function SetName({ onLogin }: { onLogin: (name: string) => void }) {
const [userName, setUserName] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault();
if(userName.trim()) {
onLogin(userName);
}
}
return (
<div className="SetName-Body">
<div className="login-box">
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div className="input-box">
<span className="icon">
<MdPerson />
</span>
<input
required
value={userName}
onChange={(e) => setUserName(e.target.value)} />
<label>Name</label>
</div>
<div>
<button className="SetName-button" type="submit">Login in</button>
</div>
</form>
</div>
</div>
);
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment