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 MinecraftButton from "@/components/button/minecraft-button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { redirect } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { ReactElement } from "react";
|
import { FormEvent, ReactElement, useState } from "react";
|
||||||
import SimpleTooltip from "@/components/simple-tooltip";
|
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.
|
* Props for a player search.
|
||||||
@ -23,14 +27,25 @@ type PlayerSearchProps = {
|
|||||||
* @returns the search component jsx
|
* @returns the search component jsx
|
||||||
*/
|
*/
|
||||||
const PlayerSearch = ({ query }: PlayerSearchProps): ReactElement => {
|
const PlayerSearch = ({ query }: PlayerSearchProps): ReactElement => {
|
||||||
const handleRedirect = async (form: FormData): Promise<void> => {
|
const router: AppRouterInstance = useRouter();
|
||||||
"use server";
|
const [loading, setLoading] = useState<boolean>(false); // If the search is loading
|
||||||
redirect(`/player/${form.get("query")}`);
|
|
||||||
|
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 (
|
return (
|
||||||
<form
|
<form
|
||||||
className="flex flex-col gap-7 justify-center items-center"
|
className="flex flex-col gap-7 justify-center items-center"
|
||||||
action={handleRedirect}
|
onSubmit={handleRedirect}
|
||||||
>
|
>
|
||||||
{/* Input */}
|
{/* Input */}
|
||||||
<div className="w-full flex flex-col gap-3">
|
<div className="w-full flex flex-col gap-3">
|
||||||
@ -48,7 +63,12 @@ const PlayerSearch = ({ query }: PlayerSearchProps): ReactElement => {
|
|||||||
|
|
||||||
{/* Search */}
|
{/* Search */}
|
||||||
<SimpleTooltip content="Click to 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>
|
</SimpleTooltip>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import MinecraftButton from "@/components/button/minecraft-button";
|
import MinecraftButton from "@/components/button/minecraft-button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
@ -10,10 +12,12 @@ import {
|
|||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { capitalize } from "@/app/common/string-utils";
|
import { capitalize } from "@/app/common/string-utils";
|
||||||
import { redirect } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { ReactElement } from "react";
|
import { FormEvent, ReactElement, useState } from "react";
|
||||||
import { ServerPlatform } from "restfulmc-lib";
|
import { ServerPlatform } from "restfulmc-lib";
|
||||||
import SimpleTooltip from "@/components/simple-tooltip";
|
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.
|
* Props for a server search.
|
||||||
@ -22,7 +26,7 @@ type ServerSearchProps = {
|
|||||||
/**
|
/**
|
||||||
* The original platform to query for.
|
* The original platform to query for.
|
||||||
*/
|
*/
|
||||||
platform: ServerPlatform | undefined;
|
platform: string | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The original hostname to query for.
|
* The original hostname to query for.
|
||||||
@ -41,21 +45,36 @@ const ServerSearch = ({
|
|||||||
platform,
|
platform,
|
||||||
hostname,
|
hostname,
|
||||||
}: ServerSearchProps): ReactElement => {
|
}: ServerSearchProps): ReactElement => {
|
||||||
const handleRedirect = async (form: FormData): Promise<void> => {
|
const router: AppRouterInstance = useRouter();
|
||||||
"use server";
|
const [loading, setLoading] = useState<boolean>(false); // If the search is loading
|
||||||
redirect(`/server/${form.get("platform")}/${form.get("hostname")}`);
|
|
||||||
|
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 (
|
return (
|
||||||
<form
|
<form
|
||||||
className="flex flex-col gap-7 justify-center items-center"
|
className="flex flex-col gap-7 justify-center items-center"
|
||||||
action={handleRedirect}
|
onSubmit={handleRedirect}
|
||||||
>
|
>
|
||||||
{/* Input */}
|
{/* Input */}
|
||||||
<div className="w-full flex gap-2">
|
<div className="w-full flex gap-2">
|
||||||
{/* Platform Selection */}
|
{/* Platform Selection */}
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<Label htmlFor="platform">Platform</Label>
|
<Label htmlFor="platform">Platform</Label>
|
||||||
<Select name="platform" defaultValue={platform} required>
|
<Select
|
||||||
|
name="platform"
|
||||||
|
defaultValue={platform || "java"}
|
||||||
|
required
|
||||||
|
>
|
||||||
<SelectTrigger className="w-28">
|
<SelectTrigger className="w-28">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@ -91,7 +110,12 @@ const ServerSearch = ({
|
|||||||
|
|
||||||
{/* Search */}
|
{/* Search */}
|
||||||
<SimpleTooltip content="Click to 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>
|
</SimpleTooltip>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user