Merge pull request #76 from BRAVO68WEB/issue-74-Settings_Section

Issue 74 settings section
This commit is contained in:
Chirag Bhalotia 2023-06-19 21:31:43 +05:30 committed by GitHub
commit 6973dfd1ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 341 additions and 3 deletions

View File

@ -0,0 +1,7 @@
import React from 'react'
function Page() {
return <div>Page</div>;
}
export default Page;

View File

@ -0,0 +1,54 @@
import React from 'react';
function Page() {
const urls = [
{
id: 'afdas',
originalURL: 'https://www.google.com',
shortenedURL: 'https://www.google.com',
},
];
return (
<div>
<table className="min-w-full divide-y divide-gray-700">
<thead className="p-2">
<tr>
<th
scope="col"
className="py-3.5 pl-4 pr-5 text-left text-lg font-semibold text-white"
>
Original URL
</th>
<th
scope="col"
className="py-3.5 pl-4 pr-3 w-full text-left text-lg font-semibold text-white"
>
Shortened URL
</th>
</tr>
</thead>
<tbody className="divide-y p-2">
{urls.map(({ originalURL, shortenedURL, id }) => (
<tr className="bg-gray-900 rounded" key={id}>
<td className="whitespace-nowrap pl-4 pr-20 text-sm font-medium text-white">
<div className="flex items-center gap-3">
{originalURL}
</div>
</td>
<td className="whitespace-nowrap pl-4 text-sm font-medium text-white">
<div className="flex items-center gap-3">
{shortenedURL}
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default Page;

View File

@ -0,0 +1,69 @@
'use client';
import { cn } from '@/lib/utils';
import { usePathname } from 'next/navigation';
import Link from 'next/link';
const tabs = [
{
name: 'Instance Info',
href: '/dashboard/utilities/instance-info',
current: false,
},
{ name: 'Settings', href: '/dashboard/utilities/settings', current: false },
{
name: 'Config Download',
href: '/dashboard/utilities/download-config',
current: true,
},
];
export default function Example({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
function isCurrent(href: string) {
return href === pathname;
}
return (
<>
<h1 className="text-4xl mb-10">My Utilities</h1>
<div className="sm:hidden">
<label htmlFor="tabs" className="sr-only">
Select a tab
</label>
{/* Use an "onChange" listener to redirect the user to the selected tab URL. */}
<select
id="tabs"
name="tabs"
className="block w-full rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500"
defaultValue={tabs.find(tab => tab.current)?.name}
>
{tabs.map(tab => (
<option key={tab.name}>{tab.name}</option>
))}
</select>
</div>
<div className="hidden sm:block">
<div className="border-b border-gray-200">
<nav className="-mb-px flex" aria-label="Tabs">
{tabs.map(tab => (
<Link
key={tab.name}
href={tab.href}
className={cn(
isCurrent(tab.href)
? 'border-primary text-primary'
: 'border-transparent text-white',
'w-full border-b-2 py-4 px-1 text-center text-sm font-medium '
)}
aria-current={tab.current ? 'page' : undefined}
>
{tab.name}
</Link>
))}
</nav>
</div>
</div>
{children}
</>
);
}

View File

@ -0,0 +1,82 @@
"use client"
import React, { useState } from 'react';
import Button from '@/components/ui/Button';
import Input from '@/components/ui/Input';
import TagInput from '@/components/TagInput';
function Page() {
const [imageExts, setImageExts] = useState<string[]>([]);
const [fileExts, setFileExts] = useState<string[]>([]);
const addImageExt = (tag: string) => {
setImageExts(old => {
return [...old, tag];
});
};
const addFileExt = (tag: string) => {
setFileExts(old => {
return [...old, tag];
});
};
return (
<div className="flex flex-col gap-8 w-full mt-10">
<div>
<label
htmlFor="theme"
className="block text-sm font-medium leading-6 text-white"
>
Theme
</label>
<select
id="theme"
name="theme"
className="mt-2 block w-full bg-transparent rounded-md py-1.5 pl-3 pr-10 text-white sm:text-sm sm:leading-6 border-primary border"
defaultValue="dark"
>
<option value={'dark'}>Dark</option>
</select>
</div>
<div>
<label
htmlFor="Language"
className="block text-sm font-medium leading-6 text-white"
>
Language
</label>
<select
id="Language"
name="Language"
className="mt-2 bg-transparent block w-full rounded-md py-1.5 pl-3 pr-10 text-white sm:text-sm sm:leading-6 border border-primary"
defaultValue="en"
>
<option value={'en'}>English</option>
</select>
</div>
<div className="flex items-center w-full">
<Input
id="instance-url"
withLabel
label="Instance URL"
type="text"
className="w-full"
/>
</div>
<TagInput
tags={imageExts}
onAddTags={addImageExt}
placeholder="Image Extensions"
/>
<TagInput
tags={fileExts}
onAddTags={addFileExt}
placeholder="File Extensions"
/>
<Button>Save</Button>
</div>
);
}
export default Page;

View File

@ -0,0 +1,41 @@
import React, { FormEventHandler, useRef } from 'react';
import Input from './ui/Input';
import Button from './ui/Button';
interface TagInput {
tags: string[];
onAddTags: (value: string) => void;
placeholder?: string;
}
function TagInput({ tags, placeholder, onAddTags }: TagInput) {
const inputRef = useRef<HTMLInputElement>(null);
const onSubmit: FormEventHandler<HTMLFormElement> = evt => {
evt.preventDefault();
if (inputRef.current?.value && inputRef.current.value.trim() !== '') {
onAddTags(inputRef.current.value);
inputRef.current.value = '';
}
};
return (
<div className="w-full flex flex-wrap gap-2">
{tags.map((tag, index) => (
<Button key={index} className="rounded w-min m-0 items-center">
{tag}
</Button>
))}
<form onSubmit={onSubmit} className="w-40">
<Input
ref={inputRef}
type="text"
placeholder={placeholder}
className="text-lg h-full my-0 p-2"
/>
<button hidden type="submit" />
</form>
</div>
);
}
export default TagInput;

View File

@ -3,6 +3,7 @@ import React, {
InputHTMLAttributes,
LegacyRef,
MutableRefObject,
RefObject,
} from 'react';
import { cva, VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
@ -27,7 +28,7 @@ interface InputProps
VariantProps<typeof inputVariance> {
label?: string;
withLabel?: boolean;
ref?: MutableRefObject<HTMLInputElement> | RefCallBack;
ref?: MutableRefObject<HTMLInputElement> |RefObject<HTMLInputElement>| RefCallBack;
}
const Input = forwardRef<HTMLInputElement | InputProps>(

View File

@ -2343,6 +2343,13 @@
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.9.2":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec"
integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.21.9":
version "7.21.9"
resolved "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz"
@ -3700,6 +3707,21 @@
schema-utils "^3.0.0"
source-map "^0.7.3"
"@react-dnd/asap@^5.0.1":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-5.0.2.tgz#1f81f124c1cd6f39511c11a881cfb0f715343488"
integrity sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==
"@react-dnd/invariant@^4.0.1":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/invariant/-/invariant-4.0.2.tgz#b92edffca10a26466643349fac7cdfb8799769df"
integrity sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==
"@react-dnd/shallowequal@^4.0.1":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz#d1b4befa423f692fa4abf1c79209702e7d8ae4b4"
integrity sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==
"@redis/bloom@1.2.0":
version "1.2.0"
resolved "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz"
@ -5463,6 +5485,13 @@
dependencies:
"@types/react" "*"
"@types/react-tag-input@^6.6.1":
version "6.6.1"
resolved "https://registry.yarnpkg.com/@types/react-tag-input/-/react-tag-input-6.6.1.tgz#c7f12fec61a5f2b98028fa1e47ae64bd29a7c453"
integrity sha512-IaCnZu4gplbt2pR+3bD/yy9SdzsuT+fTOLeJcwYuyBw0aoHAuiTg8lKPii1fPPrV+nisxOWU3SmEqL9VwqaXuw==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@18.2.7", "@types/react@>=16":
version "18.2.7"
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.7.tgz"
@ -6983,6 +7012,11 @@ class-variance-authority@^0.6.0:
dependencies:
clsx "1.2.1"
classnames@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
clean-css@^5.2.2:
version "5.3.2"
resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz"
@ -7899,6 +7933,15 @@ dlv@^1.1.3:
resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
dnd-core@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-16.0.1.tgz#a1c213ed08961f6bd1959a28bb76f1a868360d19"
integrity sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==
dependencies:
"@react-dnd/asap" "^5.0.1"
"@react-dnd/invariant" "^4.0.1"
redux "^4.2.0"
doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz"
@ -9653,6 +9696,13 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies:
react-is "^16.7.0"
hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz"
@ -10826,7 +10876,7 @@ lodash.templatesettings@^4.0.0:
dependencies:
lodash._reinterpolate "^3.0.0"
lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.0:
lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.0, lodash@~4.17.12:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@ -12607,6 +12657,24 @@ react-colorful@^5.1.2:
resolved "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz"
integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==
react-dnd-html5-backend@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz#87faef15845d512a23b3c08d29ecfd34871688b6"
integrity sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==
dependencies:
dnd-core "^16.0.1"
react-dnd@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-16.0.1.tgz#2442a3ec67892c60d40a1559eef45498ba26fa37"
integrity sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==
dependencies:
"@react-dnd/invariant" "^4.0.1"
"@react-dnd/shallowequal" "^4.0.1"
dnd-core "^16.0.1"
fast-deep-equal "^3.1.3"
hoist-non-react-statics "^3.3.2"
react-docgen-typescript@^2.2.2:
version "2.2.2"
resolved "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz"
@ -12667,7 +12735,7 @@ react-is@18.1.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz"
integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==
react-is@^16.13.1:
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@ -12682,6 +12750,15 @@ react-refresh@^0.11.0:
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz"
integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==
react-tag-input@^6.8.1:
version "6.8.1"
resolved "https://registry.yarnpkg.com/react-tag-input/-/react-tag-input-6.8.1.tgz#bbf6e4e0765c0565470cc48a44dc4757c75784b9"
integrity sha512-eD8SCFVMGbnDP0qnlpMnalw6POJVnkOh0M7FhuVyR3u/Mf+lgAuvl+GbrtGaFZcw3qz2sWo6j3jrrHUV2gO6Cg==
dependencies:
classnames "~2.3.1"
lodash "~4.17.12"
prop-types "^15.7.2"
react@18.2.0:
version "18.2.0"
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
@ -12808,6 +12885,13 @@ redis@^4.6.6, redis@^4.6.7:
"@redis/search" "1.1.3"
"@redis/time-series" "1.0.4"
redux@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
dependencies:
"@babel/runtime" "^7.9.2"
regenerate-unicode-properties@^10.1.0:
version "10.1.0"
resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz"