Add feedback to search buttons
All checks were successful
Deploy Frontend / docker (17, 3.8.5) (push) Successful in 1m7s
All checks were successful
Deploy Frontend / docker (17, 3.8.5) (push) Successful in 1m7s
This commit is contained in:
parent
58a97708fd
commit
8b31904095
@ -1,10 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import MinecraftButton from "@/components/button/minecraft-button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { redirect } from "next/navigation";
|
||||
import { ReactElement } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { FormEvent, ReactElement, useState } from "react";
|
||||
import SimpleTooltip from "@/components/simple-tooltip";
|
||||
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
|
||||
import { Loader2 } from "lucide-react";
|
||||
|
||||
/**
|
||||
* Props for a player search.
|
||||
@ -23,14 +27,25 @@ type PlayerSearchProps = {
|
||||
* @returns the search component jsx
|
||||
*/
|
||||
const PlayerSearch = ({ query }: PlayerSearchProps): ReactElement => {
|
||||
const handleRedirect = async (form: FormData): Promise<void> => {
|
||||
"use server";
|
||||
redirect(`/player/${form.get("query")}`);
|
||||
const router: AppRouterInstance = useRouter();
|
||||
const [loading, setLoading] = useState<boolean>(false); // If the search is loading
|
||||
|
||||
const handleRedirect = async (
|
||||
event: FormEvent<HTMLFormElement>
|
||||
): Promise<void> => {
|
||||
setLoading(true); // Start loading
|
||||
event.preventDefault(); // Prevent the form from submitting
|
||||
|
||||
// Get the form data
|
||||
const form: FormData = new FormData(event.currentTarget);
|
||||
router.push(`/player/${form.get("query")}`);
|
||||
};
|
||||
|
||||
// Render the search form
|
||||
return (
|
||||
<form
|
||||
className="flex flex-col gap-7 justify-center items-center"
|
||||
action={handleRedirect}
|
||||
onSubmit={handleRedirect}
|
||||
>
|
||||
{/* Input */}
|
||||
<div className="w-full flex flex-col gap-3">
|
||||
@ -48,7 +63,12 @@ const PlayerSearch = ({ query }: PlayerSearchProps): ReactElement => {
|
||||
|
||||
{/* Search */}
|
||||
<SimpleTooltip content="Click to search">
|
||||
<MinecraftButton type="submit">Search</MinecraftButton>
|
||||
<MinecraftButton type="submit" disabled={loading}>
|
||||
{loading && (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
)}
|
||||
Search
|
||||
</MinecraftButton>
|
||||
</SimpleTooltip>
|
||||
</form>
|
||||
);
|
||||
|
@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import MinecraftButton from "@/components/button/minecraft-button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
@ -10,10 +12,12 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { capitalize } from "@/app/common/string-utils";
|
||||
import { redirect } from "next/navigation";
|
||||
import { ReactElement } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { FormEvent, ReactElement, useState } from "react";
|
||||
import { ServerPlatform } from "restfulmc-lib";
|
||||
import SimpleTooltip from "@/components/simple-tooltip";
|
||||
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
|
||||
import { Loader2 } from "lucide-react";
|
||||
|
||||
/**
|
||||
* Props for a server search.
|
||||
@ -22,7 +26,7 @@ type ServerSearchProps = {
|
||||
/**
|
||||
* The original platform to query for.
|
||||
*/
|
||||
platform: ServerPlatform | undefined;
|
||||
platform: string | undefined;
|
||||
|
||||
/**
|
||||
* The original hostname to query for.
|
||||
@ -41,21 +45,36 @@ const ServerSearch = ({
|
||||
platform,
|
||||
hostname,
|
||||
}: ServerSearchProps): ReactElement => {
|
||||
const handleRedirect = async (form: FormData): Promise<void> => {
|
||||
"use server";
|
||||
redirect(`/server/${form.get("platform")}/${form.get("hostname")}`);
|
||||
const router: AppRouterInstance = useRouter();
|
||||
const [loading, setLoading] = useState<boolean>(false); // If the search is loading
|
||||
|
||||
const handleRedirect = async (
|
||||
event: FormEvent<HTMLFormElement>
|
||||
): Promise<void> => {
|
||||
setLoading(true); // Start loading
|
||||
event.preventDefault(); // Prevent the form from submitting
|
||||
|
||||
// Get the form data
|
||||
const form: FormData = new FormData(event.currentTarget);
|
||||
router.push(`/server/${form.get("platform")}/${form.get("hostname")}`);
|
||||
};
|
||||
|
||||
// Render the search form
|
||||
return (
|
||||
<form
|
||||
className="flex flex-col gap-7 justify-center items-center"
|
||||
action={handleRedirect}
|
||||
onSubmit={handleRedirect}
|
||||
>
|
||||
{/* Input */}
|
||||
<div className="w-full flex gap-2">
|
||||
{/* Platform Selection */}
|
||||
<div className="flex flex-col gap-3">
|
||||
<Label htmlFor="platform">Platform</Label>
|
||||
<Select name="platform" defaultValue={platform} required>
|
||||
<Select
|
||||
name="platform"
|
||||
defaultValue={platform || "java"}
|
||||
required
|
||||
>
|
||||
<SelectTrigger className="w-28">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
@ -91,7 +110,12 @@ const ServerSearch = ({
|
||||
|
||||
{/* Search */}
|
||||
<SimpleTooltip content="Click to search">
|
||||
<MinecraftButton type="submit">Search</MinecraftButton>
|
||||
<MinecraftButton type="submit" disabled={loading}>
|
||||
{loading && (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
)}
|
||||
Search
|
||||
</MinecraftButton>
|
||||
</SimpleTooltip>
|
||||
</form>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user