add basic player page
Some checks failed
Deploy App / docker (ubuntu-latest) (push) Has been cancelled
Some checks failed
Deploy App / docker (ubuntu-latest) (push) Has been cancelled
This commit is contained in:
parent
89c534ac86
commit
8203b10b71
@ -8,6 +8,11 @@ const nextConfig = {
|
||||
hostname: "git.fascinated.cc",
|
||||
pathname: "/**",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "api.mcutils.xyz",
|
||||
pathname: "/**",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -9,6 +9,8 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"axios": "^1.6.8",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"lucide-react": "^0.368.0",
|
||||
@ -16,6 +18,7 @@
|
||||
"next-themes": "^0.3.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-toastify": "^10.0.5",
|
||||
"tailwind-merge": "^2.2.2",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
},
|
||||
|
113
pnpm-lock.yaml
generated
113
pnpm-lock.yaml
generated
@ -5,6 +5,12 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@radix-ui/react-slot':
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2(@types/react@18.2.78)(react@18.2.0)
|
||||
axios:
|
||||
specifier: ^1.6.8
|
||||
version: 1.6.8
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0
|
||||
@ -26,6 +32,9 @@ dependencies:
|
||||
react-dom:
|
||||
specifier: ^18
|
||||
version: 18.2.0(react@18.2.0)
|
||||
react-toastify:
|
||||
specifier: ^10.0.5
|
||||
version: 10.0.5(react-dom@18.2.0)(react@18.2.0)
|
||||
tailwind-merge:
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
@ -284,6 +293,35 @@ packages:
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.78)(react@18.2.0):
|
||||
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.4
|
||||
'@types/react': 18.2.78
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-slot@1.0.2(@types/react@18.2.78)(react@18.2.0):
|
||||
resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.4
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0)
|
||||
'@types/react': 18.2.78
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@rushstack/eslint-patch@1.10.2:
|
||||
resolution: {integrity: sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==}
|
||||
dev: true
|
||||
@ -311,7 +349,6 @@ packages:
|
||||
|
||||
/@types/prop-types@15.7.12:
|
||||
resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
|
||||
dev: true
|
||||
|
||||
/@types/react-dom@18.2.25:
|
||||
resolution: {integrity: sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==}
|
||||
@ -324,7 +361,6 @@ packages:
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.12
|
||||
csstype: 3.1.3
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5):
|
||||
resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==}
|
||||
@ -564,6 +600,10 @@ packages:
|
||||
resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
|
||||
dev: true
|
||||
|
||||
/asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
dev: false
|
||||
|
||||
/available-typed-arrays@1.0.7:
|
||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -576,6 +616,16 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/axios@1.6.8:
|
||||
resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.6
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/axobject-query@3.2.1:
|
||||
resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
|
||||
dependencies:
|
||||
@ -689,6 +739,13 @@ packages:
|
||||
/color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
/combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: false
|
||||
|
||||
/commander@4.1.1:
|
||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||
engines: {node: '>= 6'}
|
||||
@ -712,7 +769,6 @@ packages:
|
||||
|
||||
/csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
dev: true
|
||||
|
||||
/damerau-levenshtein@1.0.8:
|
||||
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
||||
@ -790,6 +846,11 @@ packages:
|
||||
object-keys: 1.1.1
|
||||
dev: true
|
||||
|
||||
/delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/dequal@2.0.3:
|
||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||
engines: {node: '>=6'}
|
||||
@ -1297,6 +1358,16 @@ packages:
|
||||
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
||||
dev: true
|
||||
|
||||
/follow-redirects@1.15.6:
|
||||
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dev: false
|
||||
|
||||
/for-each@0.3.3:
|
||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||
dependencies:
|
||||
@ -1310,6 +1381,15 @@ packages:
|
||||
cross-spawn: 7.0.3
|
||||
signal-exit: 4.1.0
|
||||
|
||||
/form-data@4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: false
|
||||
|
||||
/fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
dev: true
|
||||
@ -1848,6 +1928,18 @@ packages:
|
||||
braces: 3.0.2
|
||||
picomatch: 2.3.1
|
||||
|
||||
/mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
dev: false
|
||||
|
||||
/minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
dependencies:
|
||||
@ -2201,6 +2293,10 @@ packages:
|
||||
react-is: 16.13.1
|
||||
dev: true
|
||||
|
||||
/proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
dev: false
|
||||
|
||||
/punycode@2.3.1:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
@ -2223,6 +2319,17 @@ packages:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
dev: true
|
||||
|
||||
/react-toastify@10.0.5(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==}
|
||||
peerDependencies:
|
||||
react: '>=18'
|
||||
react-dom: '>=18'
|
||||
dependencies:
|
||||
clsx: 2.1.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react@18.2.0:
|
||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -1,7 +1,9 @@
|
||||
import Container from "@/components/container";
|
||||
import ThemeProvider from "@/components/theme-provider";
|
||||
import { Inter } from "next/font/google";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
|
||||
import { Inter } from "next/font/google";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import "./globals.css";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
@ -17,6 +19,7 @@ export default function RootLayout({
|
||||
<head />
|
||||
<body>
|
||||
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
|
||||
<ToastContainer theme="dark" />
|
||||
<Container>{children}</Container>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
|
@ -13,12 +13,15 @@ const buttons: Button[] = [
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="text-center flex flex-col justify-center">
|
||||
<h1 className="text-4xl">Minecraft Utilities</h1>
|
||||
<p className="text-lg">
|
||||
We provide a convenient API for Minecraft, simplifying the usage for players and developers.
|
||||
</p>
|
||||
<h1 className="text-4xl mb-1">Minecraft Utilities</h1>
|
||||
<div className="text-lg">
|
||||
<p>Minecraft Utilities offers you many endpoints to get information about a minecraft server or a player.</p>
|
||||
<p>
|
||||
You can use this information on your minecraft server or website. We offer you a simple and easy to use API.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex flex-row gap-2 justify-center">
|
||||
<div className="mt-6 flex flex-row gap-2 justify-center">
|
||||
{buttons.map((button, index) => {
|
||||
return (
|
||||
<Link
|
||||
|
13
src/app/player/page.tsx
Normal file
13
src/app/player/page.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import PlayerSearch from "@/components/player-search";
|
||||
|
||||
export default function Player() {
|
||||
return (
|
||||
<div className="h-full flex flex-col items-center">
|
||||
<div className="mb-4 text-center">
|
||||
<h1 className="text-xl">Search for a Player</h1>
|
||||
<p>You can enter a players uuid or username to get information about the player.</p>
|
||||
</div>
|
||||
<PlayerSearch />
|
||||
</div>
|
||||
);
|
||||
}
|
18
src/common/web-request.ts
Normal file
18
src/common/web-request.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { API_ENDPOINT } from "@/consts";
|
||||
import axios from "axios";
|
||||
|
||||
export default class WebRequest {
|
||||
private API_ENDPOINT: string = API_ENDPOINT;
|
||||
|
||||
/**
|
||||
* Gets a response from the server
|
||||
*
|
||||
* @param endpoint the endpoint to send the request to
|
||||
* @returns the response from the server
|
||||
*/
|
||||
public static get(endpoint: string) {
|
||||
return axios.get(API_ENDPOINT + endpoint, {
|
||||
validateStatus: () => true, // Do not throw an error on non-200 status codes
|
||||
});
|
||||
}
|
||||
}
|
77
src/components/player-search.tsx
Normal file
77
src/components/player-search.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
"use client";
|
||||
|
||||
import WebRequest from "@/common/web-request";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
import { Button } from "./ui/button";
|
||||
import { Input } from "./ui/input";
|
||||
|
||||
export default function PlayerSearch() {
|
||||
const [playerId, setPlayerId] = useState<string | null>(null);
|
||||
const [player, setPlayer] = useState<any | null>(null);
|
||||
|
||||
const handleSearch = () => {
|
||||
if (playerId === null || playerId.length <= 0) {
|
||||
toast.error("Please enter a player ID");
|
||||
return;
|
||||
}
|
||||
searchPlayer(playerId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Searches for a player by their id
|
||||
*
|
||||
* @param playerId the player's id
|
||||
*/
|
||||
const searchPlayer = async (playerId: string) => {
|
||||
const response = await WebRequest.get("/player/" + playerId);
|
||||
if (response.status !== 200) {
|
||||
toast.error("Player not found");
|
||||
return;
|
||||
}
|
||||
const { cache, player } = response.data;
|
||||
setPlayer(player);
|
||||
console.log(player);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-8">
|
||||
<div className="flex items-center gap-2">
|
||||
<Input className="w-[200px]" placeholder="Player ID" onChange={(e) => setPlayerId(e.target.value)} />
|
||||
<Button onClick={() => handleSearch()}>Search</Button>
|
||||
</div>
|
||||
|
||||
{player && (
|
||||
<div className="bg-secondary rounded-lg p-2 min-w-[600px] max-w-full">
|
||||
<div className="flex gap-4 p-2">
|
||||
<Image src={player.skin.parts.head} alt="The player's Head" width={150} height={150} />
|
||||
<div className="flex flex-col gap-1 mt-2">
|
||||
<p>
|
||||
Unique ID: <span className="font-bold">{player.uniqueId}</span>
|
||||
</p>
|
||||
<p>
|
||||
Name: <span className="font-bold">{player.username}</span>
|
||||
</p>
|
||||
<div className="mt-2">
|
||||
<p>Skin Parts</p>
|
||||
<div className="flex gap-2">
|
||||
{Object.keys(player.skin.parts).map((part: any, index: number) => {
|
||||
return (
|
||||
<p key={index}>
|
||||
<Link className="text-primary" href={player.skin.parts[part]} target="_blank">
|
||||
{part}
|
||||
</Link>
|
||||
</p>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
47
src/components/ui/button.tsx
Normal file
47
src/components/ui/button.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/common/utils";
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
||||
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export interface ButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||
VariantProps<typeof buttonVariants> {
|
||||
asChild?: boolean;
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;
|
||||
}
|
||||
);
|
||||
Button.displayName = "Button";
|
||||
|
||||
export { Button, buttonVariants };
|
22
src/components/ui/input.tsx
Normal file
22
src/components/ui/input.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/common/utils";
|
||||
|
||||
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||
|
||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(({ className, type, ...props }, ref) => {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
Input.displayName = "Input";
|
||||
|
||||
export { Input };
|
1
src/consts.ts
Normal file
1
src/consts.ts
Normal file
@ -0,0 +1 @@
|
||||
export const API_ENDPOINT = "https://api.mcutils.xyz";
|
Loading…
x
Reference in New Issue
Block a user