Compare commits
7 Commits
merge_mstr
...
loginCompo
| Author | SHA1 | Date | |
|---|---|---|---|
| f7044df992 | |||
| 9ed87f60ed | |||
| 4822bca2d2 | |||
| 93b51225cc | |||
| 20cc70cc34 | |||
| d7b5c4cf42 | |||
| a1a23f5e2c |
@@ -1,5 +1,5 @@
|
|||||||
import type { Preview } from "@storybook/react";
|
import type { Preview } from "@storybook/react";
|
||||||
import "../app/global.css";
|
import '../app/global.css';
|
||||||
|
|
||||||
const preview: Preview = {
|
const preview: Preview = {
|
||||||
parameters: {
|
parameters: {
|
||||||
|
|||||||
3448
front_end_portserver/package-lock.json
generated
Normal file
@@ -12,20 +12,19 @@
|
|||||||
"build-storybook": "storybook build"
|
"build-storybook": "storybook build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@hookform/resolvers": "^3.3.2",
|
||||||
"@radix-ui/react-checkbox": "^1.0.4",
|
"@radix-ui/react-checkbox": "^1.0.4",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-popover": "^1.0.7",
|
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
"@tanstack/react-table": "^8.10.7",
|
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"date-fns": "^2.30.0",
|
|
||||||
"lucide-react": "^0.292.0",
|
"lucide-react": "^0.292.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-hook-form": "^7.48.2",
|
||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
"tailwindcss-animate": "^1.0.7"
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@storybook/addon-essentials": "7.5.3",
|
"@storybook/addon-essentials": "7.5.3",
|
||||||
|
|||||||
5
front_end_portserver/src/assets/carbon_dot-mark-red.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="carbon:dot-mark">
|
||||||
|
<path id="Vector" d="M8.25 15C12.116 15 15.25 11.866 15.25 8C15.25 4.13401 12.116 1 8.25 1C4.38401 1 1.25 4.13401 1.25 8C1.25 11.866 4.38401 15 8.25 15Z" fill="#BA1A1A"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 304 B |
5
front_end_portserver/src/assets/carbon_dot-mark.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="carbon:dot-mark">
|
||||||
|
<path id="Vector" d="M8.25 15C12.116 15 15.25 11.866 15.25 8C15.25 4.13401 12.116 1 8.25 1C4.38401 1 1.25 4.13401 1.25 8C1.25 11.866 4.38401 15 8.25 15Z" fill="#1B9828"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 304 B |
5
front_end_portserver/src/assets/cog_white.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="Icon/cog">
|
||||||
|
<path id="Icon" fill-rule="evenodd" clip-rule="evenodd" d="M9.19148 2.53673C8.88826 1.28772 7.11194 1.28772 6.80872 2.53673C6.61285 3.34357 5.68846 3.72646 4.97943 3.29445C3.88184 2.62567 2.6258 3.88172 3.29457 4.97931C3.72659 5.68833 3.34369 6.61272 2.53685 6.8086C1.28785 7.11182 1.28785 8.88813 2.53685 9.19135C3.34369 9.38723 3.72659 10.3116 3.29457 11.0206C2.6258 12.1182 3.88184 13.3743 4.97943 12.7055C5.68846 12.2735 6.61285 12.6564 6.80872 13.4632C7.11194 14.7122 8.88826 14.7122 9.19148 13.4632C9.38735 12.6564 10.3117 12.2735 11.0208 12.7055C12.1184 13.3743 13.3744 12.1182 12.7056 11.0206C12.2736 10.3116 12.6565 9.38723 13.4633 9.19135C14.7123 8.88813 14.7123 7.11182 13.4633 6.8086C12.6565 6.61272 12.2736 5.68833 12.7056 4.97931C13.3744 3.88172 12.1184 2.62568 11.0208 3.29445C10.3117 3.72646 9.38735 3.34357 9.19148 2.53673ZM8.0001 10.4C9.32558 10.4 10.4001 9.32546 10.4001 7.99998C10.4001 6.67449 9.32558 5.59998 8.0001 5.59998C6.67461 5.59998 5.6001 6.67449 5.6001 7.99998C5.6001 9.32546 6.67461 10.4 8.0001 10.4Z" fill="#F5F5F5"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
12
front_end_portserver/src/assets/tabler_bulb-filled.svg
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="tabler:bulb-filled" clip-path="url(#clip0_39_14671)">
|
||||||
|
<g id="Group">
|
||||||
|
<path id="Vector" d="M2.66658 7.33337C2.8365 7.33356 2.99993 7.39863 3.12349 7.51527C3.24705 7.63192 3.3214 7.79134 3.33136 7.96097C3.34132 8.1306 3.28613 8.29763 3.17707 8.42793C3.06801 8.55823 2.91331 8.64197 2.74458 8.66204L2.66658 8.66671H1.99991C1.82999 8.66652 1.66656 8.60145 1.543 8.48481C1.41944 8.36816 1.34509 8.20874 1.33513 8.03911C1.32517 7.86948 1.38036 7.70245 1.48942 7.57215C1.59848 7.44185 1.75318 7.35811 1.92191 7.33804L1.99991 7.33337H2.66658ZM7.99991 1.33337C8.1632 1.3334 8.3208 1.39334 8.44283 1.50185C8.56485 1.61036 8.64281 1.75987 8.66191 1.92204L8.66658 2.00004V2.66671C8.66639 2.83663 8.60133 3.00006 8.48468 3.12362C8.36803 3.24718 8.20861 3.32153 8.03898 3.33149C7.86935 3.34145 7.70233 3.28626 7.57202 3.1772C7.44172 3.06814 7.35798 2.91344 7.33791 2.74471L7.33325 2.66671V2.00004C7.33325 1.82323 7.40348 1.65366 7.52851 1.52864C7.65353 1.40361 7.8231 1.33337 7.99991 1.33337ZM13.9999 7.33337C14.1698 7.33356 14.3333 7.39863 14.4568 7.51527C14.5804 7.63192 14.6547 7.79134 14.6647 7.96097C14.6747 8.1306 14.6195 8.29763 14.5104 8.42793C14.4013 8.55823 14.2466 8.64197 14.0779 8.66204L13.9999 8.66671H13.3332C13.1633 8.66652 12.9999 8.60145 12.8763 8.48481C12.7528 8.36816 12.6784 8.20874 12.6685 8.03911C12.6585 7.86948 12.7137 7.70245 12.8228 7.57215C12.9318 7.44185 13.0865 7.35811 13.2552 7.33804L13.3332 7.33337H13.9999ZM3.26191 3.26204C3.37671 3.14726 3.52944 3.0783 3.69146 3.06811C3.85348 3.05793 4.01364 3.10721 4.14191 3.20671L4.20458 3.26204L4.67125 3.72871C4.79081 3.84868 4.86023 4.00966 4.8654 4.17896C4.87057 4.34826 4.8111 4.51318 4.69908 4.64023C4.58706 4.76727 4.43088 4.84691 4.26226 4.86297C4.09365 4.87904 3.92524 4.83032 3.79125 4.72671L3.72858 4.67137L3.26191 4.20471C3.13693 4.07969 3.06672 3.91015 3.06672 3.73337C3.06672 3.5566 3.13693 3.38706 3.26191 3.26204ZM11.7952 3.26204C11.9152 3.14248 12.0762 3.07306 12.2455 3.06789C12.4148 3.06272 12.5797 3.12218 12.7068 3.23421C12.8338 3.34623 12.9135 3.50241 12.9295 3.67102C12.9456 3.83964 12.8969 4.00805 12.7932 4.14204L12.7379 4.20471L12.2712 4.67137C12.1513 4.79094 11.9903 4.86036 11.821 4.86553C11.6517 4.8707 11.4868 4.81123 11.3597 4.69921C11.2327 4.58719 11.153 4.43101 11.137 4.26239C11.1209 4.09378 11.1696 3.92537 11.2732 3.79137L11.3286 3.72871L11.7952 3.26204ZM9.33325 12C9.51006 12 9.67963 12.0703 9.80465 12.1953C9.92967 12.3203 9.99991 12.4899 9.99991 12.6667C9.99991 13.1971 9.7892 13.7058 9.41413 14.0809C9.03905 14.456 8.53035 14.6667 7.99991 14.6667C7.46948 14.6667 6.96077 14.456 6.5857 14.0809C6.21063 13.7058 5.99991 13.1971 5.99991 12.6667C5.99993 12.5034 6.05988 12.3458 6.16839 12.2238C6.2769 12.1018 6.42641 12.0238 6.58858 12.0047L6.66658 12H9.33325ZM7.99991 4.00004C8.83944 4.00004 9.65769 4.26419 10.3388 4.75507C11.0198 5.24595 11.5292 5.93868 11.7946 6.73513C12.0601 7.53158 12.0683 8.39137 11.818 9.19271C11.5676 9.99405 11.0715 10.6963 10.3999 11.2C10.308 11.2691 10.1999 11.3132 10.0859 11.328L9.99991 11.3334H5.99991C5.85567 11.3334 5.71531 11.2866 5.59991 11.2C4.92829 10.6963 4.43218 9.99405 4.18186 9.19271C3.93154 8.39137 3.9397 7.53158 4.20518 6.73513C4.47066 5.93868 4.98001 5.24595 5.66107 4.75507C6.34213 4.26419 7.16038 4.00004 7.99991 4.00004Z" fill="#FFBC11"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_39_14671">
|
||||||
|
<rect width="16" height="16" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
73
front_end_portserver/src/components/Login/assets/LoginBg.svg
Normal file
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 97 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="Icon/eye-off">
|
||||||
|
<g id="Icon">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.70711 2.29289C3.31658 1.90237 2.68342 1.90237 2.29289 2.29289C1.90237 2.68342 1.90237 3.31658 2.29289 3.70711L16.2929 17.7071C16.6834 18.0976 17.3166 18.0976 17.7071 17.7071C18.0976 17.3166 18.0976 16.6834 17.7071 16.2929L16.2339 14.8197C17.7715 13.5924 18.939 11.9211 19.5424 9.99996C18.2681 5.94288 14.4778 3 10.0002 3C8.37665 3 6.84344 3.38692 5.48779 4.07358L3.70711 2.29289ZM7.96813 6.55391L9.48201 8.0678C9.6473 8.02358 9.82102 8 10.0003 8C11.1048 8 12.0003 8.89543 12.0003 10C12.0003 10.1792 11.9767 10.353 11.9325 10.5182L13.4463 12.0321C13.7983 11.4366 14.0003 10.7419 14.0003 10C14.0003 7.79086 12.2094 6 10.0003 6C9.25838 6 8.56367 6.20197 7.96813 6.55391Z" fill="black"/>
|
||||||
|
<path d="M12.4541 16.6967L9.74965 13.9923C7.74013 13.8681 6.1322 12.2601 6.00798 10.2506L2.33492 6.57754C1.50063 7.57223 0.856368 8.73169 0.458008 10C1.73228 14.0571 5.52257 17 10.0002 17C10.8469 17 11.6689 16.8948 12.4541 16.6967Z" fill="black"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
16
front_end_portserver/src/components/Login/assets/eye-on.svg
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
|
||||||
|
<!-- License: CC Attribution. Made by Deemak Daksina: https://dribbble.com/deemakdaksina -->
|
||||||
|
<svg fill="#000000" width="20px" height="20px" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|
||||||
|
<title/>
|
||||||
|
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path d="M94.9936,44.6718C83.6788,27.7025,70.155,11.9989,48,11.9989S12.3212,27.7025,1.0064,44.6718a6.0063,6.0063,0,0,0,0,6.6564C12.3212,68.2975,25.845,84.0011,48,84.0011S83.6788,68.2975,94.9936,51.3282A6.0063,6.0063,0,0,0,94.9936,44.6718ZM48,72.0007C35.2672,72.0007,25.3294,65.21,13.2646,48,25.3294,30.7905,35.2672,23.9993,48,23.9993S70.6706,30.7905,82.7354,48C70.6706,65.21,60.7328,72.0007,48,72.0007Z"/>
|
||||||
|
|
||||||
|
<path d="M48,36A12,12,0,1,0,60,48,12.0161,12.0161,0,0,0,48,36Z"/>
|
||||||
|
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 722 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="Icon/lock-closed">
|
||||||
|
<path id="Icon" fill-rule="evenodd" clip-rule="evenodd" d="M5 9V7C5 4.23858 7.23858 2 10 2C12.7614 2 15 4.23858 15 7V9C16.1046 9 17 9.89543 17 11V16C17 17.1046 16.1046 18 15 18H5C3.89543 18 3 17.1046 3 16V11C3 9.89543 3.89543 9 5 9ZM13 7V9H7V7C7 5.34315 8.34315 4 10 4C11.6569 4 13 5.34315 13 7Z" fill="black"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 446 B |
@@ -0,0 +1,8 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g id="Icon/mail">
|
||||||
|
<g id="Icon">
|
||||||
|
<path d="M2.00333 5.88355L9.99995 9.88186L17.9967 5.8835C17.9363 4.83315 17.0655 4 16 4H4C2.93452 4 2.06363 4.83318 2.00333 5.88355Z" fill="black"/>
|
||||||
|
<path d="M18 8.1179L9.99995 12.1179L2 8.11796V14C2 15.1046 2.89543 16 4 16H16C17.1046 16 18 15.1046 18 14V8.1179Z" fill="black"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 425 B |
@@ -0,0 +1,9 @@
|
|||||||
|
import loginBg from '@/components/Login/assets/LoginBg.svg'
|
||||||
|
|
||||||
|
export const Background = (
|
||||||
|
) => {
|
||||||
|
|
||||||
|
return(
|
||||||
|
<img src={loginBg} className='absolute w-full h-full no-repeat bg-cover' ></img>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Button , buttonVariants } from "@/components/ui/button";
|
||||||
|
|
||||||
|
interface ButtonProps {
|
||||||
|
variant ?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
|
||||||
|
size ?: 'default' | 'sm' | 'lg' | 'icon' ;
|
||||||
|
label ?: string;
|
||||||
|
styling?: string;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Buttons = ( {...props}:ButtonProps )=> {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={
|
||||||
|
(buttonVariants({
|
||||||
|
variant: props.variant,
|
||||||
|
size: props.size
|
||||||
|
}),
|
||||||
|
props.styling
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{props.label}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { Input } from "@/components/ui/input"
|
||||||
|
import { Label } from "@/components/ui/label"
|
||||||
|
import { useState } from "react"
|
||||||
|
|
||||||
|
import mail from "@/components/Login/assets/mail.svg"
|
||||||
|
import lock from "@/components/Login/assets/lock-closed.svg"
|
||||||
|
import eyeOff from "@/components/Login/assets/eye-off.svg"
|
||||||
|
import eyeOn from "@/components/Login/assets/eye-on.svg"
|
||||||
|
|
||||||
|
export interface InputWithLabelProps {
|
||||||
|
labelValue ?: string;
|
||||||
|
// typeName ?: string;
|
||||||
|
placeHolderName ?: string;
|
||||||
|
togglePasswordVisibility ?:boolean;
|
||||||
|
type ?: 'password' | 'email';
|
||||||
|
onClick ?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const InputWithLabel = ({
|
||||||
|
...props
|
||||||
|
}:InputWithLabelProps) => {
|
||||||
|
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
|
const togglePasswordVisibility = () => {
|
||||||
|
setShowPassword(!showPassword);
|
||||||
|
};
|
||||||
|
|
||||||
|
const srcIcon = props.type?.toLowerCase() === 'email' ? mail : props.type?.toLowerCase() === 'password' ? lock : '';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className= "flex flex-col items-start gap-4">
|
||||||
|
<Label > { props.labelValue } </Label>
|
||||||
|
<div className= "relative">
|
||||||
|
<img src= { srcIcon } className="w-10% absolute top-0 left-0 py-2.5 pl-2" />
|
||||||
|
{(props.type === 'password') && (
|
||||||
|
<img
|
||||||
|
src={props.togglePasswordVisibility ? eyeOn : eyeOff}
|
||||||
|
className="w-10% absolute py-2.5 right-0 pr-2 "
|
||||||
|
onClick={togglePasswordVisibility}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Input
|
||||||
|
// type= { props.typeName }
|
||||||
|
placeholder= { props.placeHolderName }
|
||||||
|
className={`w-full px-8 `}
|
||||||
|
type={props.type?.toLowerCase() === 'password' && showPassword ? 'text' : props.type}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
interface LinkBtnProps {
|
||||||
|
value ?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LinkBtn = ({
|
||||||
|
...props
|
||||||
|
}:LinkBtnProps ) => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-end gap-8">
|
||||||
|
<a className="text-black font-inter text-sm font-normal underline">{props.value}</a>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { Background } from "./Background"
|
||||||
|
import { LogoSismedika } from "./Logo"
|
||||||
|
import { EmailInput, PasswordInput } from "../stories/Input.stories"
|
||||||
|
import { ForgetPasswordLink } from "../stories/Link.stories"
|
||||||
|
import { LoginTitle } from "../stories/Title.stories"
|
||||||
|
import { LoginButton } from "../stories/Button.stories"
|
||||||
|
|
||||||
|
export const LoginForm = (
|
||||||
|
) => {
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<div className="relative w-full h-full">
|
||||||
|
<div className="object-cover"><Background /></div>
|
||||||
|
<div className="flex justify-center item-center object-contain">
|
||||||
|
<div className="inline-grid scale-75 gap-5">
|
||||||
|
<div className="flex justify-center items-center pb-4">
|
||||||
|
<LogoSismedika />
|
||||||
|
</div>
|
||||||
|
<LoginTitle />
|
||||||
|
<EmailInput />
|
||||||
|
<div className="gap-5">
|
||||||
|
<PasswordInput />
|
||||||
|
<ForgetPasswordLink />
|
||||||
|
</div>
|
||||||
|
<LoginButton />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
import logoSismedika from '@/components/Login/assets/LogoSismedika.svg'
|
||||||
|
|
||||||
|
export const LogoSismedika = (
|
||||||
|
) => {
|
||||||
|
|
||||||
|
return(
|
||||||
|
<img src={logoSismedika} ></img>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Label } from "@/components/ui/label"
|
||||||
|
|
||||||
|
|
||||||
|
interface TitleProps {
|
||||||
|
|
||||||
|
value : string;
|
||||||
|
value2 ?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Title = ({
|
||||||
|
...props
|
||||||
|
}: TitleProps ) => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col justify-center items-center gap-1">
|
||||||
|
<Label className="text-primary-text text-3xl font-inter font-bold">{props.value}</Label>
|
||||||
|
<Label className="text-secondary-text text-xs font-inter font-normal text-[#637381]">{props.value2}</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Background } from "../loginComponents/Background";
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Component/Login/LoginBackground'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export const LoginBg= () => {
|
||||||
|
return(
|
||||||
|
<Background/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
import { RowLabelValue } from '../../components/main/cardInstrument/RowLabelValue';
|
|
||||||
|
import { Buttons } from '../loginComponents/Button';
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
||||||
const meta = {
|
const meta = {
|
||||||
title: 'Component/Main/Row Label Value',
|
title: 'Component/Login/Button',
|
||||||
component: RowLabelValue,
|
component: Buttons,
|
||||||
parameters: {
|
parameters: {
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
||||||
layout: 'centered',
|
layout: 'centered',
|
||||||
@@ -12,18 +13,28 @@ const meta = {
|
|||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
||||||
tags: ['autodocs'],
|
tags: ['autodocs'],
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
||||||
argTypes: {
|
args : {
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
},
|
||||||
} satisfies Meta<typeof RowLabelValue>;
|
argTypes: {
|
||||||
|
|
||||||
|
},
|
||||||
|
} satisfies Meta<typeof Buttons>;
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof meta>;
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
||||||
export const Initial: Story = {
|
|
||||||
args: {
|
export const LoginButton = (args:Story) => {
|
||||||
label:'',
|
return(
|
||||||
value:''
|
<Buttons
|
||||||
},
|
variant='default'
|
||||||
};
|
size='lg'
|
||||||
|
label='Log In'
|
||||||
|
styling='flex w-full p-3.5 justify-center items-center gap-2.5 rounded-md border border-black bg-[#F15A29]'
|
||||||
|
|
||||||
|
{...args}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { Meta, StoryObj } from "@storybook/react";
|
||||||
|
import { InputWithLabel } from "../loginComponents/Inputs";
|
||||||
|
import { boolean } from "zod";
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: "Component/Login/Input",
|
||||||
|
component: InputWithLabel,
|
||||||
|
tags: ['autodocs'],
|
||||||
|
|
||||||
|
parameters: {
|
||||||
|
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
||||||
|
layout: 'centered',
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
labelValue: "Label Name",
|
||||||
|
placeHolderName : "Place Holder Name",
|
||||||
|
},
|
||||||
|
|
||||||
|
argTypes: {
|
||||||
|
type: {
|
||||||
|
options: ['email', 'password'],
|
||||||
|
control: { type: 'radio' },
|
||||||
|
},
|
||||||
|
togglePasswordVisibility : {action : boolean},
|
||||||
|
onClick: { action: 'clicked' }
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} satisfies Meta<typeof InputWithLabel>
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
|
// export const ArgumentEmailInput: Story = {
|
||||||
|
// args: {
|
||||||
|
// labelValue: "Email",
|
||||||
|
// typeName: "Email",
|
||||||
|
// placeHolderName: "Input your Email",
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export const ArgumentPasswordInput: Story = {
|
||||||
|
// args:{
|
||||||
|
// labelValue: "Password",
|
||||||
|
// typeName: "Password",
|
||||||
|
// placeHolderName: "Input your Password",
|
||||||
|
// togglePasswordVisibility: false,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
|
||||||
|
export const EmailInput = (args:Story) => {
|
||||||
|
return(
|
||||||
|
<InputWithLabel
|
||||||
|
labelValue="Email"
|
||||||
|
type="email"
|
||||||
|
placeHolderName="Input your Email"
|
||||||
|
|
||||||
|
{...args}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PasswordInput = (args:Story) => {
|
||||||
|
return(
|
||||||
|
<InputWithLabel
|
||||||
|
labelValue="Password"
|
||||||
|
type="password"
|
||||||
|
placeHolderName="Input your Password"
|
||||||
|
{...args}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { Meta, StoryObj } from "@storybook/react";
|
||||||
|
import { LinkBtn } from "../loginComponents/LinkButton";
|
||||||
|
|
||||||
|
const meta= {
|
||||||
|
title: 'Component/Login/LinkButton',
|
||||||
|
component: LinkBtn,
|
||||||
|
tags: ['autodocs'],
|
||||||
|
parameters: {
|
||||||
|
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
||||||
|
layout: 'centered',
|
||||||
|
},
|
||||||
|
args:{
|
||||||
|
value : "Forget password",
|
||||||
|
}
|
||||||
|
|
||||||
|
}satisfies Meta<typeof LinkBtn>
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
|
export const ForgetPasswordLink = (args:Story) => {
|
||||||
|
return(
|
||||||
|
<LinkBtn value="Forget Password" {...args} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { LoginForm } from "../loginComponents/LoginForm";
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Component/Login/Forms',
|
||||||
|
tags: ['autodocs'],
|
||||||
|
component: LoginForm,
|
||||||
|
|
||||||
|
args:{
|
||||||
|
value: "value",
|
||||||
|
value2: "value2"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export const LoginForms = () => {
|
||||||
|
return(
|
||||||
|
<LoginForm/>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Meta, StoryObj } from "@storybook/react";
|
||||||
|
import {Title} from "../loginComponents/Title";
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Component/Login/Title',
|
||||||
|
component: Title,
|
||||||
|
parameters: {
|
||||||
|
layout: 'centered',
|
||||||
|
},
|
||||||
|
tags: ['autodocs'],
|
||||||
|
|
||||||
|
argTypes:{
|
||||||
|
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
value: 'value1',
|
||||||
|
value2: 'value2',
|
||||||
|
},
|
||||||
|
}satisfies Meta<typeof Title>
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
|
export const LoginTitle = (args:Story) => {
|
||||||
|
return(
|
||||||
|
<Title value={"Port Server"} value2="Welcome back! Enter your account details" {...args} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from "@/components/ui/card"
|
|
||||||
import { Rs232PropertyView } from './Rs232PropertyView';
|
|
||||||
import { IpClientPropertyView } from './IpClientPropertyView';
|
|
||||||
import { IpServerPropertyView } from './IpServerPropertyView';
|
|
||||||
import { RowIndicatorv1 } from './RowIndicatorv1';
|
|
||||||
import { IpClientType, IpServerType, Rs232Type, UdpClientType, UdpServerType, } from '../models/InstrumentModel';
|
|
||||||
|
|
||||||
interface CardProps {
|
|
||||||
titleAlat?: string,
|
|
||||||
type?: string,
|
|
||||||
lampu?: boolean,
|
|
||||||
online?: boolean,
|
|
||||||
typeDetail: Rs232Type | IpClientType | IpServerType | UdpClientType | UdpServerType
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const CardInstrument = ({
|
|
||||||
...props
|
|
||||||
}: CardProps) => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Card className="w-60 mx-auto rounded-lg overflow-hidden border-black border-solid">
|
|
||||||
<CardHeader className='bg-orange-500'>
|
|
||||||
<CardTitle>
|
|
||||||
<div className='flex justify-between'>
|
|
||||||
<div className='mx-2'>
|
|
||||||
<span className='text-white font-inter font-semibold text-base'>{props.titleAlat}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<svg
|
|
||||||
className='mt-2'
|
|
||||||
xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.19148 2.53673C8.88826 1.28772 7.11194 1.28772 6.80872 2.53673C6.61285 3.34357 5.68846 3.72646 4.97943 3.29445C3.88184 2.62567 2.6258 3.88172 3.29457 4.97931C3.72659 5.68833 3.34369 6.61272 2.53685 6.8086C1.28785 7.11182 1.28785 8.88813 2.53685 9.19135C3.34369 9.38723 3.72659 10.3116 3.29457 11.0206C2.6258 12.1182 3.88184 13.3743 4.97943 12.7055C5.68846 12.2735 6.61285 12.6564 6.80872 13.4632C7.11194 14.7122 8.88826 14.7122 9.19148 13.4632C9.38735 12.6564 10.3117 12.2735 11.0208 12.7055C12.1184 13.3743 13.3744 12.1182 12.7056 11.0206C12.2736 10.3116 12.6565 9.38723 13.4633 9.19135C14.7123 8.88813 14.7123 7.11182 13.4633 6.8086C12.6565 6.61272 12.2736 5.68833 12.7056 4.97931C13.3744 3.88172 12.1184 2.62568 11.0208 3.29445C10.3117 3.72646 9.38735 3.34357 9.19148 2.53673ZM8.0001 10.4C9.32558 10.4 10.4001 9.32546 10.4001 7.99998C10.4001 6.67449 9.32558 5.59998 8.0001 5.59998C6.67461 5.59998 5.6001 6.67449 5.6001 7.99998C5.6001 9.32546 6.67461 10.4 8.0001 10.4Z" fill="#F5F5F5" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
{/* ROW 1 & 2 START */}
|
|
||||||
<RowIndicatorv1
|
|
||||||
lampu={props.lampu}
|
|
||||||
type={props.type}
|
|
||||||
online={props.online}
|
|
||||||
blink={false}
|
|
||||||
/>
|
|
||||||
{/* ROW 1 & 2 END */}
|
|
||||||
|
|
||||||
{/* ROW 3 */}
|
|
||||||
{
|
|
||||||
props.type == 'rs232' ? (<Rs232PropertyView
|
|
||||||
type={props.type}
|
|
||||||
valueSpeed={(props.typeDetail as Rs232Type).speedValue}
|
|
||||||
valueBaud='8'
|
|
||||||
valueDataBit={(props.typeDetail as Rs232Type).dataBitValue}
|
|
||||||
valueStopBit={(props.typeDetail as Rs232Type).stopBitValue}
|
|
||||||
/>) : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
props.type == 'ipclient' ? (<IpClientPropertyView
|
|
||||||
type={props.type}
|
|
||||||
valueHost={(props.typeDetail as IpClientType).hostValue}
|
|
||||||
valuePort={(props.typeDetail as IpClientType).portValue}
|
|
||||||
/>) : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
props.type == 'ipserver' ? (<IpServerPropertyView
|
|
||||||
type={props.type}
|
|
||||||
valueListeningPort={(props.typeDetail as IpServerType).listeningPortValue}
|
|
||||||
/>) : ''
|
|
||||||
}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
import { RowLabelValue } from './RowLabelValue';
|
|
||||||
|
|
||||||
interface IpClientPropertyViewProps {
|
|
||||||
type?: string,
|
|
||||||
valueHost:string,
|
|
||||||
valuePort:string,
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IpClientPropertyView = ({
|
|
||||||
...props
|
|
||||||
}: IpClientPropertyViewProps) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* IpClient START */}
|
|
||||||
<RowLabelValue
|
|
||||||
label='Host'
|
|
||||||
value={props.valueHost}
|
|
||||||
/>
|
|
||||||
<RowLabelValue
|
|
||||||
label='Port'
|
|
||||||
value={props.valuePort}
|
|
||||||
/>
|
|
||||||
{/* IpClient END */}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
import { RowLabelValue } from './RowLabelValue';
|
|
||||||
|
|
||||||
interface IpServerPropertyViewProps {
|
|
||||||
type?: string,
|
|
||||||
valueListeningPort:string,
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IpServerPropertyView = ({
|
|
||||||
...props
|
|
||||||
}: IpServerPropertyViewProps) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* IpServer START */}
|
|
||||||
<RowLabelValue
|
|
||||||
label='Listening Port'
|
|
||||||
value={props.valueListeningPort}
|
|
||||||
/>
|
|
||||||
{/* IpServer END */}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
import { StatusTransferv1 } from './StatusTransferv1';
|
|
||||||
import { StatusOnlinev1 } from './StatusOnlinev1';
|
|
||||||
import { TypeCardv1 } from './TypeCardv1';
|
|
||||||
|
|
||||||
interface RowIndicatorv1Props {
|
|
||||||
lampu?: boolean,
|
|
||||||
type?: string;
|
|
||||||
online?: boolean;
|
|
||||||
blink?:boolean;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const RowIndicatorv1 = ({
|
|
||||||
...props
|
|
||||||
}: RowIndicatorv1Props) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className='flex justify-between mt-2 mb-3'>
|
|
||||||
{/* LAMP START */}
|
|
||||||
<StatusTransferv1
|
|
||||||
isTransferCard={props.lampu}
|
|
||||||
/>
|
|
||||||
{/* LAMP END */}
|
|
||||||
|
|
||||||
{/* Type Badge START*/}
|
|
||||||
<TypeCardv1
|
|
||||||
titleType={props.type}
|
|
||||||
/>
|
|
||||||
{/* Type Badge END */}
|
|
||||||
|
|
||||||
{/* ONLINE / OFFLINE START */}
|
|
||||||
<StatusOnlinev1
|
|
||||||
isOnlineCard={props.online}
|
|
||||||
/>
|
|
||||||
{/* ONLINE / OFFLINE END */}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
|
|
||||||
interface RowLabelValueProps {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const RowLabelValue = ({
|
|
||||||
...props
|
|
||||||
}: RowLabelValueProps) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<span className="text-inter text-sm font-normal">
|
|
||||||
{props.label}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span className="text-inter text-sm font-normal text-left">{props.value}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
import { RowLabelValue } from './RowLabelValue';
|
|
||||||
|
|
||||||
interface Rs232PropertyViewProps {
|
|
||||||
type?: string,
|
|
||||||
valueSpeed:string,
|
|
||||||
valueBaud:string,
|
|
||||||
valueDataBit:string,
|
|
||||||
valueStopBit:string
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Rs232PropertyView = ({
|
|
||||||
...props
|
|
||||||
}: Rs232PropertyViewProps) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* RS232 START */}
|
|
||||||
<RowLabelValue
|
|
||||||
label='Speed'
|
|
||||||
value={props.valueSpeed}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<RowLabelValue
|
|
||||||
label='Baud'
|
|
||||||
value={props.valueBaud}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<RowLabelValue
|
|
||||||
label='Data Bit'
|
|
||||||
value={props.valueDataBit}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<RowLabelValue
|
|
||||||
label='Stop Bit'
|
|
||||||
value={props.valueStopBit}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* RS232 END */}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
import { StatusTransferv1 } from './StatusTransferv1';
|
|
||||||
import { StatusOnlinev1 } from './StatusOnlinev1';
|
|
||||||
|
|
||||||
interface StatusCardProps {
|
|
||||||
isOnline?: boolean;
|
|
||||||
isTransferCard?:boolean;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const StatusCardv1 = ({
|
|
||||||
...props
|
|
||||||
}: StatusCardProps) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className='flex justify-between mt-2 mb-2'>
|
|
||||||
{/* LAMP START */}
|
|
||||||
<StatusTransferv1
|
|
||||||
isTransferCard={props.isTransferCard}
|
|
||||||
/>
|
|
||||||
{/* LAMP END */}
|
|
||||||
|
|
||||||
{/* ONLINE / OFFLINE START */}
|
|
||||||
<StatusOnlinev1
|
|
||||||
isOnlineCard={props.isOnline}
|
|
||||||
/>
|
|
||||||
{/* ONLINE / OFFLINE END */}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
|
|
||||||
interface StatusOnlinev1Props {
|
|
||||||
isOnlineCard?: boolean,
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const StatusOnlinev1 = ({
|
|
||||||
...props
|
|
||||||
}: StatusOnlinev1Props) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* ONLINE/OFFLINE START */}
|
|
||||||
{
|
|
||||||
props.isOnlineCard == true
|
|
||||||
? (
|
|
||||||
<>
|
|
||||||
<div>
|
|
||||||
</div>
|
|
||||||
<div className='flex justify-between'>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
|
||||||
<path d="M8.25 15C12.116 15 15.25 11.866 15.25 8C15.25 4.13401 12.116 1 8.25 1C4.38401 1 1.25 4.13401 1.25 8C1.25 11.866 4.38401 15 8.25 15Z" fill="#1B9828" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
|
|
||||||
)
|
|
||||||
: <>
|
|
||||||
<div>
|
|
||||||
</div>
|
|
||||||
<div className='flex justify-between'>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
|
||||||
<path d="M8.25 15C12.116 15 15.25 11.866 15.25 8C15.25 4.13401 12.116 1 8.25 1C4.38401 1 1.25 4.13401 1.25 8C1.25 11.866 4.38401 15 8.25 15Z" fill="#BA1A1A" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
{/* ONLINE/OFFLINE END */}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
|
|
||||||
interface StatusTransferv1Props {
|
|
||||||
isTransferCard?: boolean,
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const StatusTransferv1 = ({
|
|
||||||
...props
|
|
||||||
}: StatusTransferv1Props) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* TRANSFER CARD START */}
|
|
||||||
{
|
|
||||||
props.isTransferCard == true
|
|
||||||
? (
|
|
||||||
<>
|
|
||||||
<div>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
|
||||||
<g clip-path="url(#clip0_39_14671)">
|
|
||||||
<path d="M2.66658 7.33337C2.8365 7.33356 2.99993 7.39863 3.12349 7.51527C3.24705 7.63192 3.3214 7.79134 3.33136 7.96097C3.34132 8.1306 3.28613 8.29763 3.17707 8.42793C3.06801 8.55823 2.91331 8.64197 2.74458 8.66204L2.66658 8.66671H1.99991C1.82999 8.66652 1.66656 8.60145 1.543 8.48481C1.41944 8.36816 1.34509 8.20874 1.33513 8.03911C1.32517 7.86948 1.38036 7.70245 1.48942 7.57215C1.59848 7.44185 1.75318 7.35811 1.92191 7.33804L1.99991 7.33337H2.66658ZM7.99991 1.33337C8.1632 1.3334 8.3208 1.39334 8.44283 1.50185C8.56485 1.61036 8.64281 1.75987 8.66191 1.92204L8.66658 2.00004V2.66671C8.66639 2.83663 8.60133 3.00006 8.48468 3.12362C8.36803 3.24718 8.20861 3.32153 8.03898 3.33149C7.86935 3.34145 7.70233 3.28626 7.57202 3.1772C7.44172 3.06814 7.35798 2.91344 7.33791 2.74471L7.33325 2.66671V2.00004C7.33325 1.82323 7.40348 1.65366 7.52851 1.52864C7.65353 1.40361 7.8231 1.33337 7.99991 1.33337ZM13.9999 7.33337C14.1698 7.33356 14.3333 7.39863 14.4568 7.51527C14.5804 7.63192 14.6547 7.79134 14.6647 7.96097C14.6747 8.1306 14.6195 8.29763 14.5104 8.42793C14.4013 8.55823 14.2466 8.64197 14.0779 8.66204L13.9999 8.66671H13.3332C13.1633 8.66652 12.9999 8.60145 12.8763 8.48481C12.7528 8.36816 12.6784 8.20874 12.6685 8.03911C12.6585 7.86948 12.7137 7.70245 12.8228 7.57215C12.9318 7.44185 13.0865 7.35811 13.2552 7.33804L13.3332 7.33337H13.9999ZM3.26191 3.26204C3.37671 3.14726 3.52944 3.0783 3.69146 3.06811C3.85348 3.05793 4.01364 3.10721 4.14191 3.20671L4.20458 3.26204L4.67125 3.72871C4.79081 3.84868 4.86023 4.00966 4.8654 4.17896C4.87057 4.34826 4.8111 4.51318 4.69908 4.64023C4.58706 4.76727 4.43088 4.84691 4.26226 4.86297C4.09365 4.87904 3.92524 4.83032 3.79125 4.72671L3.72858 4.67137L3.26191 4.20471C3.13693 4.07969 3.06672 3.91015 3.06672 3.73337C3.06672 3.5566 3.13693 3.38706 3.26191 3.26204ZM11.7952 3.26204C11.9152 3.14248 12.0762 3.07306 12.2455 3.06789C12.4148 3.06272 12.5797 3.12218 12.7068 3.23421C12.8338 3.34623 12.9135 3.50241 12.9295 3.67102C12.9456 3.83964 12.8969 4.00805 12.7932 4.14204L12.7379 4.20471L12.2712 4.67137C12.1513 4.79094 11.9903 4.86036 11.821 4.86553C11.6517 4.8707 11.4868 4.81123 11.3597 4.69921C11.2327 4.58719 11.153 4.43101 11.137 4.26239C11.1209 4.09378 11.1696 3.92537 11.2732 3.79137L11.3286 3.72871L11.7952 3.26204ZM9.33325 12C9.51006 12 9.67963 12.0703 9.80465 12.1953C9.92967 12.3203 9.99991 12.4899 9.99991 12.6667C9.99991 13.1971 9.7892 13.7058 9.41413 14.0809C9.03905 14.456 8.53035 14.6667 7.99991 14.6667C7.46948 14.6667 6.96077 14.456 6.5857 14.0809C6.21063 13.7058 5.99991 13.1971 5.99991 12.6667C5.99993 12.5034 6.05988 12.3458 6.16839 12.2238C6.2769 12.1018 6.42641 12.0238 6.58858 12.0047L6.66658 12H9.33325ZM7.99991 4.00004C8.83944 4.00004 9.65769 4.26419 10.3388 4.75507C11.0198 5.24595 11.5292 5.93868 11.7946 6.73513C12.0601 7.53158 12.0683 8.39137 11.818 9.19271C11.5676 9.99405 11.0715 10.6963 10.3999 11.2C10.308 11.2691 10.1999 11.3132 10.0859 11.328L9.99991 11.3334H5.99991C5.85567 11.3334 5.71531 11.2866 5.59991 11.2C4.92829 10.6963 4.43218 9.99405 4.18186 9.19271C3.93154 8.39137 3.9397 7.53158 4.20518 6.73513C4.47066 5.93868 4.98001 5.24595 5.66107 4.75507C6.34213 4.26419 7.16038 4.00004 7.99991 4.00004Z" fill="#FFBC11" />
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_39_14671">
|
|
||||||
<rect width="16" height="16" fill="white" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
|
|
||||||
)
|
|
||||||
: <div></div>
|
|
||||||
}
|
|
||||||
{/* TRANSFER CARD END */}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
|
|
||||||
interface TypeCardv1Props {
|
|
||||||
titleType?: string;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const TypeCardv1 = ({
|
|
||||||
...props
|
|
||||||
}: TypeCardv1Props) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<span className="inline-block mb-2 bg-teal-400 bg-opacity-25 text-teal-400 px-2 py-1 rounded-md text-center font-public-sans text-xs font-bold">
|
|
||||||
{props.titleType}
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"idInstrument":"1",
|
|
||||||
"namaInstrument":"Mindray BC800",
|
|
||||||
"type":"rs232",
|
|
||||||
"instrumentTypeDetail":[
|
|
||||||
{
|
|
||||||
"label":"speed",
|
|
||||||
"value":"800"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label":"baudRate",
|
|
||||||
"value":"8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label":"dataBit",
|
|
||||||
"value":"N"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label":"stopBit",
|
|
||||||
"value":"1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idInstrument":"2",
|
|
||||||
"namaInstrument":"Mindray BC240",
|
|
||||||
"type":"rs232",
|
|
||||||
"instrumentTypeDetail":[
|
|
||||||
{
|
|
||||||
"label":"speed",
|
|
||||||
"value":"800"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label":"baudRate",
|
|
||||||
"value":"8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label":"dataBit",
|
|
||||||
"value":"N"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label":"stopBit",
|
|
||||||
"value":"1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idInstrument":"3",
|
|
||||||
"namaInstrument":"Mindray BC800",
|
|
||||||
"type":"ipclient",
|
|
||||||
"instrumentTypeDetail":[
|
|
||||||
{
|
|
||||||
"label":"host",
|
|
||||||
"value":"192.168.10.10"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label":"port",
|
|
||||||
"value":"5001"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idInstrument":"4",
|
|
||||||
"namaInstrument":"Mindray BC240",
|
|
||||||
"type":"ipserver",
|
|
||||||
"instrumentTypeDetail":[
|
|
||||||
{
|
|
||||||
"label":"listeningPort",
|
|
||||||
"value":"8001"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import '../../../../app/global.css'
|
|
||||||
import { CardInstrument } from '../cardInstrument/CardInstrument';
|
|
||||||
import { InstrumentType } from '../models/InstrumentModel';
|
|
||||||
|
|
||||||
interface InstrumentBoxProps {
|
|
||||||
totalCard?: number;
|
|
||||||
dataInstrumentType: InstrumentType[];
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const InstrumentBox = ({
|
|
||||||
...props
|
|
||||||
}: InstrumentBoxProps) => {
|
|
||||||
|
|
||||||
let col = 2;
|
|
||||||
|
|
||||||
let showData = [];
|
|
||||||
|
|
||||||
if (props.totalCard != undefined && props.totalCard > 0) {
|
|
||||||
for (let index = 0; index < props.totalCard; index++) {
|
|
||||||
showData.push([
|
|
||||||
<CardInstrument
|
|
||||||
lampu={true}
|
|
||||||
online={true}
|
|
||||||
titleAlat={props.dataInstrumentType[index].title}
|
|
||||||
type={props.dataInstrumentType[index].type}
|
|
||||||
typeDetail={props.dataInstrumentType[index].data}
|
|
||||||
/>
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className={`grid grid-cols-${col} gap-10`}>
|
|
||||||
{ showData }
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { ColumnDef } from "@tanstack/react-table";
|
|
||||||
|
|
||||||
export type PortServerData = {
|
|
||||||
id : string;
|
|
||||||
info : string;
|
|
||||||
date : Date;
|
|
||||||
type : 'status' | 'result' | 'query';
|
|
||||||
}
|
|
||||||
|
|
||||||
export type HeaderTableProps = {
|
|
||||||
data: PortServerData[];
|
|
||||||
columns: ColumnDef<PortServerData>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DropDownComponentProps = {
|
|
||||||
label: string ;
|
|
||||||
type : string ;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TableBodyProps = {
|
|
||||||
data: PortServerData[]; // Sesuaikan dengan tipe data sebenarnya
|
|
||||||
columns: ColumnDef<PortServerData>[]; // Sesuaikan dengan tipe data sebenarnya
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// export type InstrumentTypeDetail = {
|
|
||||||
// label: string;
|
|
||||||
// value: string;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export type InstrumentModel = {
|
|
||||||
// idInstrument: string;
|
|
||||||
// namaInstrument: string;
|
|
||||||
// type:string;
|
|
||||||
// instrumentTypeDetail: InstrumentTypeDetail[]
|
|
||||||
// };
|
|
||||||
|
|
||||||
export type Rs232Type = {
|
|
||||||
speedValue: string,
|
|
||||||
dataBitValue: string,
|
|
||||||
parityValue: string,
|
|
||||||
stopBitValue: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IpClientType = {
|
|
||||||
hostValue: string,
|
|
||||||
portValue: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IpServerType = {
|
|
||||||
listeningPortValue: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UdpClientType = {
|
|
||||||
hostValue: string,
|
|
||||||
portValue: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UdpServerType = {
|
|
||||||
listeningPortValue: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type InstrumentType = {
|
|
||||||
engine: string,
|
|
||||||
type: string,
|
|
||||||
title: string,
|
|
||||||
data: Rs232Type | IpClientType | IpServerType | UdpClientType | UdpServerType
|
|
||||||
};
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import { Meta, StoryObj } from "@storybook/react";
|
|
||||||
import { PortServerData } from "@/components/main/model/TableModel";
|
|
||||||
import { TableBodyComponent } from "../tableComponent/BodyTableComponent";
|
|
||||||
import { columns } from "../tableComponent/columns";
|
|
||||||
|
|
||||||
const data:PortServerData[] = [
|
|
||||||
{ id: "1", info: "Info 1", date: new Date("2023-10-30 15:26:04"), type: 'status' },
|
|
||||||
{ id: "2", info: "Info 2", date: new Date("2023-10-30 15:26:04"), type: 'result' },
|
|
||||||
{ id: "3", info: "Info 3", date: new Date("2023-10-30 15:26:04"), type: 'query' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Table/Body',
|
|
||||||
component: TableBodyComponent,
|
|
||||||
args: {
|
|
||||||
data: data,
|
|
||||||
columns: columns,
|
|
||||||
},
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
|
|
||||||
} satisfies Meta<typeof TableBodyComponent>
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>
|
|
||||||
|
|
||||||
export const PortServerBodyTables = (args: Story ) => {
|
|
||||||
return (
|
|
||||||
<TableBodyComponent data={data} columns={columns} {...args} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import { Meta, StoryObj} from "@storybook/react";
|
|
||||||
import { DataTableDemo, columns, data } from "../tableComponent/DataTable";
|
|
||||||
import DataTable from "../tableComponent/newDataTable";
|
|
||||||
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Table',
|
|
||||||
component: DataTableDemo,
|
|
||||||
parameters: {
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
tags: ['autodocs'],
|
|
||||||
args: {
|
|
||||||
data: data,
|
|
||||||
columns: columns,
|
|
||||||
},
|
|
||||||
argTypes: {
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof DataTableDemo>
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>
|
|
||||||
|
|
||||||
export const Datable = (args:Story) => {
|
|
||||||
return(
|
|
||||||
<DataTableDemo data={data} columns={columns} {...args} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DataTable2 = (args: Story) => {
|
|
||||||
return (
|
|
||||||
<DataTable data={data} columns={columns} {...args}/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
|
||||||
import { DropDownMenuComponent } from '../tableComponent/DropDownMenuComponent';
|
|
||||||
|
|
||||||
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Table/DropdownOption',
|
|
||||||
component: DropDownMenuComponent,
|
|
||||||
argTypes:{
|
|
||||||
label: {
|
|
||||||
options: ["cog", "dot",],
|
|
||||||
control: { type: 'radio' },
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
options: ['status','query','result','head'],
|
|
||||||
control: {type: 'radio'},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tags: ['autodocs'],
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof DropDownMenuComponent>;
|
|
||||||
|
|
||||||
export default meta
|
|
||||||
|
|
||||||
type Story = StoryObj<typeof meta>
|
|
||||||
|
|
||||||
export const CogDropDown = () => {
|
|
||||||
return(
|
|
||||||
<DropDownMenuComponent
|
|
||||||
label= "cog"
|
|
||||||
type= "head"
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DotDropDownStatus = (args: Story) => {
|
|
||||||
return(
|
|
||||||
<DropDownMenuComponent
|
|
||||||
label= "dot"
|
|
||||||
type= "status"
|
|
||||||
{...args}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DotDropDownQuery = (args: Story) => {
|
|
||||||
return(
|
|
||||||
<DropDownMenuComponent
|
|
||||||
label= "dot"
|
|
||||||
type= "query"
|
|
||||||
{...args}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DotDropDownResult = (args: Story) => {
|
|
||||||
return(
|
|
||||||
<DropDownMenuComponent
|
|
||||||
label= "dot"
|
|
||||||
type= "result"
|
|
||||||
{...args}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import { Meta, StoryObj } from "@storybook/react";
|
|
||||||
import { PortServerData } from "@/components/main/model/TableModel";
|
|
||||||
import { TableHeaderComponent } from "../tableComponent/HeaderTableComponent";
|
|
||||||
import { columns } from "../tableComponent/columns";
|
|
||||||
|
|
||||||
const data:PortServerData[] = [
|
|
||||||
{ id: "1", info: "Info 1", date: new Date("2023-10-30 15:26:04"), type: 'status' },
|
|
||||||
{ id: "2", info: "Info 2", date: new Date("2023-10-30 15:26:04"), type: 'result' },
|
|
||||||
{ id: "3", info: "Info 3", date: new Date("2023-10-30 15:26:04"), type: 'query' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Table/Header',
|
|
||||||
component: TableHeaderComponent,
|
|
||||||
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
args: {
|
|
||||||
data: data,
|
|
||||||
columns: columns
|
|
||||||
}
|
|
||||||
|
|
||||||
} satisfies Meta<typeof TableHeaderComponent>
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>
|
|
||||||
|
|
||||||
export const PortServerHeadTables = (args: Story) => {
|
|
||||||
return (
|
|
||||||
<TableHeaderComponent data={data} columns={columns} {...args}/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import { Meta, StoryObj } from "@storybook/react";
|
|
||||||
import { Icon } from "../tableComponent/IconComponent";
|
|
||||||
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Table/Icon',
|
|
||||||
component: Icon,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
tags: ['autodocs'],
|
|
||||||
argTypes: {
|
|
||||||
type: {
|
|
||||||
options: ['cog', 'dot'],
|
|
||||||
control: { type: 'radio' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof Icon>
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>
|
|
||||||
|
|
||||||
export const CogIcon = (args:Story) => {
|
|
||||||
return (
|
|
||||||
<Icon type='cog' {...args} />
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DotIcon = (args:Story) => {
|
|
||||||
return (
|
|
||||||
<Icon type='dot' {...args} />
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import { TableBody, TableRow, TableCell } from '@/components/ui/table';
|
|
||||||
import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
|
|
||||||
import { TableBodyProps } from '@/components/main/model/TableModel';
|
|
||||||
|
|
||||||
|
|
||||||
export const TableBodyComponent = ({ data, columns }:TableBodyProps) => {
|
|
||||||
const table = useReactTable({
|
|
||||||
data,
|
|
||||||
columns,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
})
|
|
||||||
return (
|
|
||||||
<TableBody>
|
|
||||||
{table.getRowModel().rows?.length ? (
|
|
||||||
table.getRowModel().rows.map((row) => (
|
|
||||||
<TableRow
|
|
||||||
key={row.id}
|
|
||||||
data-state={row.getIsSelected() && "selected"}
|
|
||||||
>
|
|
||||||
{row.getVisibleCells().map((cell) => (
|
|
||||||
<TableCell key={cell.id}>
|
|
||||||
{flexRender(
|
|
||||||
cell.column.columnDef.cell,
|
|
||||||
cell.getContext()
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
colSpan={columns.length}
|
|
||||||
className="h-24 text-center"
|
|
||||||
>
|
|
||||||
No results.
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</TableBody>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import {
|
|
||||||
ColumnDef,
|
|
||||||
ColumnFiltersState,
|
|
||||||
SortingState,
|
|
||||||
VisibilityState,
|
|
||||||
flexRender,
|
|
||||||
getCoreRowModel,
|
|
||||||
getFilteredRowModel,
|
|
||||||
getPaginationRowModel,
|
|
||||||
getSortedRowModel,
|
|
||||||
useReactTable,
|
|
||||||
} from "@tanstack/react-table"
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/components/ui/dropdown-menu"
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "@/components/ui/table"
|
|
||||||
import { DateDisplay } from "./DateDisplay"
|
|
||||||
import { CogIcon, DotIcon } from "../stories/Icon.stories"
|
|
||||||
import "../../../../app/global.css"
|
|
||||||
|
|
||||||
export const data: PortServer[] = [
|
|
||||||
{
|
|
||||||
id: "m5gr84i9",
|
|
||||||
info: "800 Cobas Status",
|
|
||||||
date: new Date("2023-10-30 15:26:04"),
|
|
||||||
type: "status",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "3u1reuv4",
|
|
||||||
info: "Incoming 800 Cobas Result",
|
|
||||||
date: new Date("2023-10-30 15:26:04"),
|
|
||||||
type: "result",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "derv1ws0",
|
|
||||||
info: "Incoming 800 Cobas Query",
|
|
||||||
date: new Date("2023-10-30 15:26:04"),
|
|
||||||
type: "query",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
export type PortServer = {
|
|
||||||
id: string
|
|
||||||
info: string
|
|
||||||
date: Date
|
|
||||||
type : 'status' | 'result' | 'query'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const columns: ColumnDef<PortServer>[] = [
|
|
||||||
{
|
|
||||||
accessorKey: "date",
|
|
||||||
header: "Date",
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const date = new Date(row.getValue("date"))
|
|
||||||
return(
|
|
||||||
<div className="text-[#637381] bg-[#919EAB29] rounded-md border-4 border-[#919EAB29]">
|
|
||||||
<DateDisplay date={date}/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: "info",
|
|
||||||
header: "Info",
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<div className="capitalize">{row.getValue("info")}</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "actions",
|
|
||||||
header:() => {
|
|
||||||
return(
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
|
||||||
<CogIcon />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end" >
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={() => {}}
|
|
||||||
>
|
|
||||||
<span>Change Password</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
enableHiding: false,
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const type = row.original
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
|
||||||
<DotIcon />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
{
|
|
||||||
type.type?.toLowerCase() == 'status' ? (
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={() => {}}
|
|
||||||
>
|
|
||||||
Info
|
|
||||||
</DropdownMenuItem>
|
|
||||||
) : ''
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type.type?.toLowerCase() == 'result' ? (
|
|
||||||
<>
|
|
||||||
<DropdownMenuItem onClick={() => {}} >
|
|
||||||
Raw Data
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>
|
|
||||||
Result
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>
|
|
||||||
Export
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</>
|
|
||||||
) : ''
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type.type?.toLowerCase() == 'query' ? (
|
|
||||||
<>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>
|
|
||||||
Raw Data
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>
|
|
||||||
Query Response
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>
|
|
||||||
Export
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</>
|
|
||||||
) : ''
|
|
||||||
}
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export interface DataTableProps {
|
|
||||||
data: PortServer[]; // Properti untuk data tabel
|
|
||||||
columns: ColumnDef<PortServer>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DataTableDemo = ({
|
|
||||||
data,
|
|
||||||
columns,
|
|
||||||
}: DataTableProps) => {
|
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
React.useState<VisibilityState>({})
|
|
||||||
const [rowSelection, setRowSelection] = React.useState({})
|
|
||||||
|
|
||||||
const table = useReactTable({
|
|
||||||
data,
|
|
||||||
columns,
|
|
||||||
onSortingChange: setSorting,
|
|
||||||
onColumnFiltersChange: setColumnFilters,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
getPaginationRowModel: getPaginationRowModel(),
|
|
||||||
getSortedRowModel: getSortedRowModel(),
|
|
||||||
getFilteredRowModel: getFilteredRowModel(),
|
|
||||||
onColumnVisibilityChange: setColumnVisibility,
|
|
||||||
onRowSelectionChange: setRowSelection,
|
|
||||||
state: {
|
|
||||||
sorting,
|
|
||||||
columnFilters,
|
|
||||||
columnVisibility,
|
|
||||||
rowSelection,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="rounded-md border">
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
|
||||||
<TableRow key={headerGroup.id}>
|
|
||||||
{headerGroup.headers.map((header) => {
|
|
||||||
return (
|
|
||||||
<TableHead key={header.id}>
|
|
||||||
{header.isPlaceholder
|
|
||||||
? null
|
|
||||||
: flexRender(
|
|
||||||
header.column.columnDef.header,
|
|
||||||
header.getContext()
|
|
||||||
)}
|
|
||||||
</TableHead>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{table.getRowModel().rows?.length ? (
|
|
||||||
table.getRowModel().rows.map((row) => (
|
|
||||||
<TableRow
|
|
||||||
key={row.id}
|
|
||||||
data-state={row.getIsSelected() && "selected"}
|
|
||||||
>
|
|
||||||
{row.getVisibleCells().map((cell) => (
|
|
||||||
<TableCell key={cell.id}>
|
|
||||||
{flexRender(
|
|
||||||
cell.column.columnDef.cell,
|
|
||||||
cell.getContext()
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
colSpan={columns.length}
|
|
||||||
className="h-24 text-center"
|
|
||||||
>
|
|
||||||
No results.
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
// DateDisplay.tsx
|
|
||||||
interface DateDisplayProps {
|
|
||||||
date: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DateDisplay = ({ date }: DateDisplayProps) => {
|
|
||||||
const formattedDate = new Intl.DateTimeFormat("id-ID", {
|
|
||||||
day: "2-digit",
|
|
||||||
month: "short",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
second: "2-digit",
|
|
||||||
}).format(date);
|
|
||||||
|
|
||||||
return <label>{formattedDate}</label>;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { DropDownComponentProps } from "@/components/main/model/TableModel";
|
|
||||||
import { CogIcon, DotIcon } from "../stories/Icon.stories"
|
|
||||||
import { Button } from "@/components/ui/button"
|
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
|
||||||
|
|
||||||
|
|
||||||
export const DropDownMenuComponent = ({label, type}:DropDownComponentProps) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
|
||||||
{label.toLowerCase() === 'cog' && (
|
|
||||||
<CogIcon />
|
|
||||||
)}
|
|
||||||
{label.toLowerCase() === 'dot' && (
|
|
||||||
<DotIcon />
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
{type.toLowerCase() === 'status' && (
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={() => {}}
|
|
||||||
>
|
|
||||||
Info
|
|
||||||
</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
{type.toLowerCase() === 'result' && (
|
|
||||||
<>
|
|
||||||
<DropdownMenuItem onClick={() => {}} >Raw Data</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>Result</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>Export</DropdownMenuItem>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{type.toLowerCase() === 'query' && (
|
|
||||||
<>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>Raw Data</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>Query Response</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => {}}>Export</DropdownMenuItem>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{type.toLowerCase() === 'head' && (
|
|
||||||
<DropdownMenuItem onClick={() => {}}>Change Password</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</>
|
|
||||||
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { HeaderTableProps } from "@/components/main/model/TableModel";
|
|
||||||
import { TableHeader, TableRow, TableHead } from "@/components/ui/table";
|
|
||||||
import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
|
|
||||||
|
|
||||||
export const TableHeaderComponent = ({ data, columns }:HeaderTableProps) => {
|
|
||||||
|
|
||||||
const table = useReactTable({
|
|
||||||
data,
|
|
||||||
columns,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableHeader>
|
|
||||||
{table.getHeaderGroups().map((headerGroup: any) => (
|
|
||||||
<TableRow key={headerGroup.id}>
|
|
||||||
{headerGroup.headers.map((header: any) => (
|
|
||||||
<TableHead key={header.id}>
|
|
||||||
{header.isPlaceholder
|
|
||||||
? null
|
|
||||||
: flexRender(
|
|
||||||
header.column.columnDef.header,
|
|
||||||
typeof header.getContext === 'function' ? header.getContext() : {}
|
|
||||||
)}
|
|
||||||
</TableHead>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableHeader>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import cog from "@/assets/cog.svg"
|
|
||||||
import dot from "@/assets/dots-vertical.svg"
|
|
||||||
|
|
||||||
interface IconProps {
|
|
||||||
type ?: "cog" | "dot";
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Icon = ({
|
|
||||||
...props
|
|
||||||
}:IconProps) => {
|
|
||||||
return(
|
|
||||||
<img
|
|
||||||
src={props.type?.toLowerCase() === 'cog' ? cog : props.type?.toLowerCase() === 'dot' ? dot : '' }
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { PortServerData } from "@/components/main/model/TableModel"
|
|
||||||
import { ColumnDef } from "@tanstack/react-table"
|
|
||||||
import { DateDisplay } from "./DateDisplay"
|
|
||||||
import { CogDropDown } from "../stories/DropDownMenu.stories"
|
|
||||||
import { DropDownMenuComponent } from "./DropDownMenuComponent"
|
|
||||||
|
|
||||||
export const columns: ColumnDef<PortServerData>[] = [
|
|
||||||
{
|
|
||||||
accessorKey: "date",
|
|
||||||
header: "Date",
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const date = new Date(row.getValue("date"))
|
|
||||||
return(
|
|
||||||
<div className="text-[#637381] bg-[#919EAB29] rounded-md border-4 border-[#919EAB29]">
|
|
||||||
<DateDisplay date={date}/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: "info",
|
|
||||||
header: "Info",
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<div className="capitalize">{row.getValue("info")}</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "actions",
|
|
||||||
header:() => {
|
|
||||||
return(
|
|
||||||
<CogDropDown />
|
|
||||||
)
|
|
||||||
},
|
|
||||||
enableHiding: false,
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const type = row.original
|
|
||||||
return (
|
|
||||||
<DropDownMenuComponent label="dot" type={type.type}/>
|
|
||||||
)}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import { Table} from "@/components/ui/table";
|
|
||||||
import { TableBodyComponent } from "./BodyTableComponent";
|
|
||||||
import { TableHeaderComponent } from "./HeaderTableComponent";
|
|
||||||
import { PortServerData } from "@/components/main/model/TableModel";
|
|
||||||
import { ColumnDef } from "@tanstack/react-table";
|
|
||||||
|
|
||||||
interface DataTableprops {
|
|
||||||
data: PortServerData[];
|
|
||||||
columns: ColumnDef<PortServerData>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const DataTable = ({data, columns }:DataTableprops) => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="rounded-md border">
|
|
||||||
<Table>
|
|
||||||
<TableHeaderComponent data={data} columns={columns} />
|
|
||||||
<TableBodyComponent data={data} columns={columns} />
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DataTable;
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import { cva, type VariantProps } from "class-variance-authority"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
|
|
||||||
const badgeVariants = cva(
|
|
||||||
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
||||||
{
|
|
||||||
variants: {
|
|
||||||
variant: {
|
|
||||||
default:
|
|
||||||
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
||||||
secondary:
|
|
||||||
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
||||||
destructive:
|
|
||||||
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
||||||
outline: "text-foreground",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
defaultVariants: {
|
|
||||||
variant: "default",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export interface BadgeProps
|
|
||||||
extends React.HTMLAttributes<HTMLDivElement>,
|
|
||||||
VariantProps<typeof badgeVariants> {}
|
|
||||||
|
|
||||||
function Badge({ className, variant, ...props }: BadgeProps) {
|
|
||||||
return (
|
|
||||||
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Badge, badgeVariants }
|
|
||||||
28
front_end_portserver/src/components/ui/checkbox.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
|
||||||
|
import { Check } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Checkbox = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CheckboxPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<CheckboxPrimitive.Indicator
|
||||||
|
className={cn("flex items-center justify-center text-current")}
|
||||||
|
>
|
||||||
|
<Check className="h-4 w-4" />
|
||||||
|
</CheckboxPrimitive.Indicator>
|
||||||
|
</CheckboxPrimitive.Root>
|
||||||
|
))
|
||||||
|
Checkbox.displayName = CheckboxPrimitive.Root.displayName
|
||||||
|
|
||||||
|
export { Checkbox }
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
|
||||||
import { Check, ChevronRight, Circle } from "lucide-react"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
|
|
||||||
const DropdownMenu = DropdownMenuPrimitive.Root
|
|
||||||
|
|
||||||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
|
||||||
|
|
||||||
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
|
||||||
|
|
||||||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
|
||||||
|
|
||||||
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
|
||||||
|
|
||||||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
|
||||||
|
|
||||||
const DropdownMenuSubTrigger = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
||||||
inset?: boolean
|
|
||||||
}
|
|
||||||
>(({ className, inset, children, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.SubTrigger
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
|
|
||||||
inset && "pl-8",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
<ChevronRight className="ml-auto h-4 w-4" />
|
|
||||||
</DropdownMenuPrimitive.SubTrigger>
|
|
||||||
))
|
|
||||||
DropdownMenuSubTrigger.displayName =
|
|
||||||
DropdownMenuPrimitive.SubTrigger.displayName
|
|
||||||
|
|
||||||
const DropdownMenuSubContent = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.SubContent
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
DropdownMenuSubContent.displayName =
|
|
||||||
DropdownMenuPrimitive.SubContent.displayName
|
|
||||||
|
|
||||||
const DropdownMenuContent = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
||||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.Portal>
|
|
||||||
<DropdownMenuPrimitive.Content
|
|
||||||
ref={ref}
|
|
||||||
sideOffset={sideOffset}
|
|
||||||
className={cn(
|
|
||||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
</DropdownMenuPrimitive.Portal>
|
|
||||||
))
|
|
||||||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
|
||||||
|
|
||||||
const DropdownMenuItem = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
|
||||||
inset?: boolean
|
|
||||||
}
|
|
||||||
>(({ className, inset, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.Item
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
||||||
inset && "pl-8",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
|
||||||
|
|
||||||
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
||||||
>(({ className, children, checked, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.CheckboxItem
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
checked={checked}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
||||||
<DropdownMenuPrimitive.ItemIndicator>
|
|
||||||
<Check className="h-4 w-4" />
|
|
||||||
</DropdownMenuPrimitive.ItemIndicator>
|
|
||||||
</span>
|
|
||||||
{children}
|
|
||||||
</DropdownMenuPrimitive.CheckboxItem>
|
|
||||||
))
|
|
||||||
DropdownMenuCheckboxItem.displayName =
|
|
||||||
DropdownMenuPrimitive.CheckboxItem.displayName
|
|
||||||
|
|
||||||
const DropdownMenuRadioItem = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
||||||
>(({ className, children, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.RadioItem
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
||||||
<DropdownMenuPrimitive.ItemIndicator>
|
|
||||||
<Circle className="h-2 w-2 fill-current" />
|
|
||||||
</DropdownMenuPrimitive.ItemIndicator>
|
|
||||||
</span>
|
|
||||||
{children}
|
|
||||||
</DropdownMenuPrimitive.RadioItem>
|
|
||||||
))
|
|
||||||
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
|
|
||||||
|
|
||||||
const DropdownMenuLabel = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
|
||||||
inset?: boolean
|
|
||||||
}
|
|
||||||
>(({ className, inset, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.Label
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"px-2 py-1.5 text-sm font-semibold",
|
|
||||||
inset && "pl-8",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
|
||||||
|
|
||||||
const DropdownMenuSeparator = React.forwardRef<
|
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.Separator
|
|
||||||
ref={ref}
|
|
||||||
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
|
||||||
|
|
||||||
const DropdownMenuShortcut = ({
|
|
||||||
className,
|
|
||||||
...props
|
|
||||||
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
|
|
||||||
|
|
||||||
export {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuCheckboxItem,
|
|
||||||
DropdownMenuRadioItem,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuShortcut,
|
|
||||||
DropdownMenuGroup,
|
|
||||||
DropdownMenuPortal,
|
|
||||||
DropdownMenuSub,
|
|
||||||
DropdownMenuSubContent,
|
|
||||||
DropdownMenuSubTrigger,
|
|
||||||
DropdownMenuRadioGroup,
|
|
||||||
}
|
|
||||||
176
front_end_portserver/src/components/ui/form.tsx
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||||
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
ControllerProps,
|
||||||
|
FieldPath,
|
||||||
|
FieldValues,
|
||||||
|
FormProvider,
|
||||||
|
useFormContext,
|
||||||
|
} from "react-hook-form"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { Label } from "@/components/ui/label"
|
||||||
|
|
||||||
|
const Form = FormProvider
|
||||||
|
|
||||||
|
type FormFieldContextValue<
|
||||||
|
TFieldValues extends FieldValues = FieldValues,
|
||||||
|
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
||||||
|
> = {
|
||||||
|
name: TName
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormFieldContext = React.createContext<FormFieldContextValue>(
|
||||||
|
{} as FormFieldContextValue
|
||||||
|
)
|
||||||
|
|
||||||
|
const FormField = <
|
||||||
|
TFieldValues extends FieldValues = FieldValues,
|
||||||
|
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
||||||
|
>({
|
||||||
|
...props
|
||||||
|
}: ControllerProps<TFieldValues, TName>) => {
|
||||||
|
return (
|
||||||
|
<FormFieldContext.Provider value={{ name: props.name }}>
|
||||||
|
<Controller {...props} />
|
||||||
|
</FormFieldContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const useFormField = () => {
|
||||||
|
const fieldContext = React.useContext(FormFieldContext)
|
||||||
|
const itemContext = React.useContext(FormItemContext)
|
||||||
|
const { getFieldState, formState } = useFormContext()
|
||||||
|
|
||||||
|
const fieldState = getFieldState(fieldContext.name, formState)
|
||||||
|
|
||||||
|
if (!fieldContext) {
|
||||||
|
throw new Error("useFormField should be used within <FormField>")
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id } = itemContext
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name: fieldContext.name,
|
||||||
|
formItemId: `${id}-form-item`,
|
||||||
|
formDescriptionId: `${id}-form-item-description`,
|
||||||
|
formMessageId: `${id}-form-item-message`,
|
||||||
|
...fieldState,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FormItemContextValue = {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormItemContext = React.createContext<FormItemContextValue>(
|
||||||
|
{} as FormItemContextValue
|
||||||
|
)
|
||||||
|
|
||||||
|
const FormItem = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => {
|
||||||
|
const id = React.useId()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormItemContext.Provider value={{ id }}>
|
||||||
|
<div ref={ref} className={cn("space-y-2", className)} {...props} />
|
||||||
|
</FormItemContext.Provider>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
FormItem.displayName = "FormItem"
|
||||||
|
|
||||||
|
const FormLabel = React.forwardRef<
|
||||||
|
React.ElementRef<typeof LabelPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
|
||||||
|
>(({ className, ...props }, ref) => {
|
||||||
|
const { error, formItemId } = useFormField()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Label
|
||||||
|
ref={ref}
|
||||||
|
className={cn(error && "text-destructive", className)}
|
||||||
|
htmlFor={formItemId}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
FormLabel.displayName = "FormLabel"
|
||||||
|
|
||||||
|
const FormControl = React.forwardRef<
|
||||||
|
React.ElementRef<typeof Slot>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof Slot>
|
||||||
|
>(({ ...props }, ref) => {
|
||||||
|
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Slot
|
||||||
|
ref={ref}
|
||||||
|
id={formItemId}
|
||||||
|
aria-describedby={
|
||||||
|
!error
|
||||||
|
? `${formDescriptionId}`
|
||||||
|
: `${formDescriptionId} ${formMessageId}`
|
||||||
|
}
|
||||||
|
aria-invalid={!!error}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
FormControl.displayName = "FormControl"
|
||||||
|
|
||||||
|
const FormDescription = React.forwardRef<
|
||||||
|
HTMLParagraphElement,
|
||||||
|
React.HTMLAttributes<HTMLParagraphElement>
|
||||||
|
>(({ className, ...props }, ref) => {
|
||||||
|
const { formDescriptionId } = useFormField()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p
|
||||||
|
ref={ref}
|
||||||
|
id={formDescriptionId}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
FormDescription.displayName = "FormDescription"
|
||||||
|
|
||||||
|
const FormMessage = React.forwardRef<
|
||||||
|
HTMLParagraphElement,
|
||||||
|
React.HTMLAttributes<HTMLParagraphElement>
|
||||||
|
>(({ className, children, ...props }, ref) => {
|
||||||
|
const { error, formMessageId } = useFormField()
|
||||||
|
const body = error ? String(error?.message) : children
|
||||||
|
|
||||||
|
if (!body) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p
|
||||||
|
ref={ref}
|
||||||
|
id={formMessageId}
|
||||||
|
className={cn("text-sm font-medium text-destructive", className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{body}
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
FormMessage.displayName = "FormMessage"
|
||||||
|
|
||||||
|
export {
|
||||||
|
useFormField,
|
||||||
|
Form,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormMessage,
|
||||||
|
FormField,
|
||||||
|
}
|
||||||
25
front_end_portserver/src/components/ui/input.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/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,114 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
|
|
||||||
const Table = React.forwardRef<
|
|
||||||
HTMLTableElement,
|
|
||||||
React.HTMLAttributes<HTMLTableElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<div className="relative w-full overflow-auto">
|
|
||||||
<table
|
|
||||||
ref={ref}
|
|
||||||
className={cn("w-full caption-bottom text-sm", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
Table.displayName = "Table"
|
|
||||||
|
|
||||||
const TableHeader = React.forwardRef<
|
|
||||||
HTMLTableSectionElement,
|
|
||||||
React.HTMLAttributes<HTMLTableSectionElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
|
|
||||||
))
|
|
||||||
TableHeader.displayName = "TableHeader"
|
|
||||||
|
|
||||||
const TableBody = React.forwardRef<
|
|
||||||
HTMLTableSectionElement,
|
|
||||||
React.HTMLAttributes<HTMLTableSectionElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<tbody
|
|
||||||
ref={ref}
|
|
||||||
className={cn("[&_tr:last-child]:border-0", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
TableBody.displayName = "TableBody"
|
|
||||||
|
|
||||||
const TableFooter = React.forwardRef<
|
|
||||||
HTMLTableSectionElement,
|
|
||||||
React.HTMLAttributes<HTMLTableSectionElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<tfoot
|
|
||||||
ref={ref}
|
|
||||||
className={cn("bg-primary font-medium text-primary-foreground", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
TableFooter.displayName = "TableFooter"
|
|
||||||
|
|
||||||
const TableRow = React.forwardRef<
|
|
||||||
HTMLTableRowElement,
|
|
||||||
React.HTMLAttributes<HTMLTableRowElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<tr
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
TableRow.displayName = "TableRow"
|
|
||||||
|
|
||||||
const TableHead = React.forwardRef<
|
|
||||||
HTMLTableCellElement,
|
|
||||||
React.ThHTMLAttributes<HTMLTableCellElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<th
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
TableHead.displayName = "TableHead"
|
|
||||||
|
|
||||||
const TableCell = React.forwardRef<
|
|
||||||
HTMLTableCellElement,
|
|
||||||
React.TdHTMLAttributes<HTMLTableCellElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<td
|
|
||||||
ref={ref}
|
|
||||||
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
TableCell.displayName = "TableCell"
|
|
||||||
|
|
||||||
const TableCaption = React.forwardRef<
|
|
||||||
HTMLTableCaptionElement,
|
|
||||||
React.HTMLAttributes<HTMLTableCaptionElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<caption
|
|
||||||
ref={ref}
|
|
||||||
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
TableCaption.displayName = "TableCaption"
|
|
||||||
|
|
||||||
export {
|
|
||||||
Table,
|
|
||||||
TableHeader,
|
|
||||||
TableBody,
|
|
||||||
TableFooter,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
TableCell,
|
|
||||||
TableCaption,
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
import { CardInstrument } from '../../components/main/cardInstrument/CardInstrument';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Card',
|
|
||||||
component: CardInstrument,
|
|
||||||
parameters: {
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof CardInstrument>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// Rs 232 Cobas Online NoTransfer
|
|
||||||
export const rs232CobasOnlineNoTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'COBAS 800',
|
|
||||||
type: 'rs232',
|
|
||||||
lampu: true,
|
|
||||||
online: true,
|
|
||||||
typeDetail: {
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Rs 232 Cobas Online Transfer
|
|
||||||
export const rs232CobasOnlineTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'COBAS 800',
|
|
||||||
type: 'rs232',
|
|
||||||
lampu: false,
|
|
||||||
online: true,
|
|
||||||
typeDetail: {
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Rs 232 Cobas Offline Transfer
|
|
||||||
export const rs232CobasOfflineTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'COBAS 800',
|
|
||||||
type: 'rs232',
|
|
||||||
lampu: false,
|
|
||||||
online: false,
|
|
||||||
typeDetail: {
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ipclient Mindray Online No Transfer
|
|
||||||
export const ipclientMindrayBC800OnlineNoTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'Mindray BC800',
|
|
||||||
type: 'ipclient',
|
|
||||||
lampu: true,
|
|
||||||
online: true,
|
|
||||||
typeDetail: {
|
|
||||||
hostValue: "192.168.10.10",
|
|
||||||
portValue: "5001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ipclient Mindray Online Transfer
|
|
||||||
export const ipclientMindrayBC800OnlineTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'Mindray BC800',
|
|
||||||
type: 'ipclient',
|
|
||||||
lampu: false,
|
|
||||||
online: true,
|
|
||||||
typeDetail: {
|
|
||||||
hostValue: "192.168.10.10",
|
|
||||||
portValue: "5001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ip Client Offline Transfer
|
|
||||||
export const ipclientMindrayBC800OfflineTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'Mindray BC800',
|
|
||||||
type: 'ipclient',
|
|
||||||
lampu: false,
|
|
||||||
online: false,
|
|
||||||
typeDetail: {
|
|
||||||
hostValue: "192.168.10.10",
|
|
||||||
portValue: "5001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ip Server Mindray Online No Transfer
|
|
||||||
export const ipserverMindrayBC240OnlineNoTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'Mindray BC240',
|
|
||||||
type: 'ipserver',
|
|
||||||
lampu: true,
|
|
||||||
online: true,
|
|
||||||
typeDetail: {
|
|
||||||
listeningPortValue:"8001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ip Server Mindray Online Transfer
|
|
||||||
export const ipserverMindrayBC240OnlineTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'Mindray BC240',
|
|
||||||
type: 'ipserver',
|
|
||||||
lampu: false,
|
|
||||||
online: true,
|
|
||||||
typeDetail:{
|
|
||||||
listeningPortValue:"8001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ip Server Offline Transfer
|
|
||||||
export const ipserverMindrayBC240OfflineTransfer: Story = {
|
|
||||||
args: {
|
|
||||||
titleAlat: 'Mindray BC240',
|
|
||||||
type: 'ipserver',
|
|
||||||
lampu: false,
|
|
||||||
online: false,
|
|
||||||
typeDetail:{
|
|
||||||
listeningPortValue:"8001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
import { IpClientPropertyView } from '../../components/main/cardInstrument/IpClientPropertyView';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Ipclient',
|
|
||||||
component: IpClientPropertyView,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof IpClientPropertyView>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
||||||
export const Ipclient: Story = {
|
|
||||||
args: {
|
|
||||||
type:''
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
import { IpServerPropertyView } from '../../components/main/cardInstrument/IpServerPropertyView';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Ipserver',
|
|
||||||
component: IpServerPropertyView,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof IpServerPropertyView>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
||||||
export const Ipclient: Story = {
|
|
||||||
args: {
|
|
||||||
type:''
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { RowIndicatorv1 } from '@/components/main/cardInstrument/Rowindicatorv1';
|
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Row Indicator',
|
|
||||||
component: RowIndicatorv1,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof RowIndicatorv1>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
||||||
export const Initial: Story = {
|
|
||||||
args: {
|
|
||||||
type:''
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
import { Rs232PropertyView } from '../../components/main/cardInstrument/Rs232PropertyView';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Rs232',
|
|
||||||
component: Rs232PropertyView,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof Rs232PropertyView>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
||||||
export const Rs232: Story = {
|
|
||||||
args: {
|
|
||||||
type:''
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { StatusCardv1 } from '@/components/main/cardInstrument/StatusCardv1';
|
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Status card',
|
|
||||||
component: StatusCardv1,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof StatusCardv1>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
||||||
export const Initial: Story = {
|
|
||||||
args: {
|
|
||||||
isOnline:false
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { TypeCardv1 } from '@/components/main/cardInstrument/TypeCardv1';
|
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Type Card',
|
|
||||||
component: TypeCardv1,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof TypeCardv1>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
||||||
export const Initial: Story = {
|
|
||||||
args: {
|
|
||||||
titleType:''
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
import { InstrumentBox } from '@/components/main/instrumentBox/InstrumentBox';
|
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
|
||||||
const meta = {
|
|
||||||
title: 'Component/Main/Instrument Box',
|
|
||||||
component: InstrumentBox,
|
|
||||||
parameters: {
|
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
|
||||||
tags: ['autodocs'],
|
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
||||||
argTypes: {
|
|
||||||
// backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof InstrumentBox>;
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof meta>;
|
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
|
||||||
|
|
||||||
// Instrument 1 Alat
|
|
||||||
export const Instrument1Alat: Story = {
|
|
||||||
args: {
|
|
||||||
totalCard:1,
|
|
||||||
dataInstrumentType:[
|
|
||||||
{
|
|
||||||
engine:'astm',
|
|
||||||
title:'Cobas800',
|
|
||||||
type:'rs232',
|
|
||||||
data:{
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instrument 2 Alat
|
|
||||||
export const Instrument2Alat: Story = {
|
|
||||||
args: {
|
|
||||||
totalCard:2,
|
|
||||||
dataInstrumentType:[
|
|
||||||
{
|
|
||||||
engine:'astm',
|
|
||||||
title:'Cobas800',
|
|
||||||
type:'rs232',
|
|
||||||
data:{
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
engine:'astm',
|
|
||||||
title:'Axsym 100',
|
|
||||||
type:'rs232',
|
|
||||||
data:{
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instrument 3 Alat
|
|
||||||
export const Instrument3Alat: Story = {
|
|
||||||
args: {
|
|
||||||
totalCard:3,
|
|
||||||
dataInstrumentType:[
|
|
||||||
{
|
|
||||||
engine:'astm',
|
|
||||||
title:'Cobas800',
|
|
||||||
type:'rs232',
|
|
||||||
data:{
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
engine:'astm',
|
|
||||||
title:'Axsym 100',
|
|
||||||
type:'rs232',
|
|
||||||
data:{
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
engine:'mindray',
|
|
||||||
title:'Mindray BC800',
|
|
||||||
type:'ipclient',
|
|
||||||
data:{
|
|
||||||
hostValue:"192.168.10.10",
|
|
||||||
portValue:"5001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instrument 4 Alat
|
|
||||||
export const Instrument4Alat: Story = {
|
|
||||||
args: {
|
|
||||||
totalCard:4,
|
|
||||||
dataInstrumentType:[
|
|
||||||
{
|
|
||||||
engine:'astm',
|
|
||||||
title:'Cobas800',
|
|
||||||
type:'rs232',
|
|
||||||
data:{
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
engine:'astm',
|
|
||||||
title:'Axsym 100',
|
|
||||||
type:'rs232',
|
|
||||||
data:{
|
|
||||||
speedValue: '800',
|
|
||||||
dataBitValue: 'N',
|
|
||||||
parityValue: '',
|
|
||||||
stopBitValue: '1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
engine:'mindray',
|
|
||||||
title:'Mindray BC800',
|
|
||||||
type:'ipclient',
|
|
||||||
data:{
|
|
||||||
hostValue:"192.168.10.10",
|
|
||||||
portValue:"5001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
engine:'mindray',
|
|
||||||
title:'Mindray BC240',
|
|
||||||
type:'ipserver',
|
|
||||||
data:{
|
|
||||||
listeningPortValue:"8001"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
14
front_end_portserver_old/.eslintrc.cjs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: { browser: true, es2020: true },
|
||||||
|
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', 'plugin:storybook/recommended'],
|
||||||
|
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
plugins: ['react-refresh'],
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': [
|
||||||
|
'warn',
|
||||||
|
{ allowConstantExport: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
24
front_end_portserver_old/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
19
front_end_portserver_old/.storybook/main.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import type { StorybookConfig } from "@storybook/react-vite";
|
||||||
|
|
||||||
|
const config: StorybookConfig = {
|
||||||
|
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
|
||||||
|
addons: [
|
||||||
|
"@storybook/addon-links",
|
||||||
|
"@storybook/addon-essentials",
|
||||||
|
"@storybook/addon-onboarding",
|
||||||
|
"@storybook/addon-interactions",
|
||||||
|
],
|
||||||
|
framework: {
|
||||||
|
name: "@storybook/react-vite",
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
docs: {
|
||||||
|
autodocs: "tag",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default config;
|
||||||
15
front_end_portserver_old/.storybook/preview.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import type { Preview } from "@storybook/react";
|
||||||
|
|
||||||
|
const preview: Preview = {
|
||||||
|
parameters: {
|
||||||
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||||
|
controls: {
|
||||||
|
matchers: {
|
||||||
|
color: /(background|color)$/i,
|
||||||
|
date: /Date$/i,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default preview;
|
||||||
27
front_end_portserver_old/README.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# React + TypeScript + Vite
|
||||||
|
|
||||||
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
|
Currently, two official plugins are available:
|
||||||
|
|
||||||
|
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||||
|
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||||
|
|
||||||
|
## Expanding the ESLint configuration
|
||||||
|
|
||||||
|
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
|
||||||
|
|
||||||
|
- Configure the top-level `parserOptions` property like this:
|
||||||
|
|
||||||
|
```js
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module',
|
||||||
|
project: ['./tsconfig.json', './tsconfig.node.json'],
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
|
||||||
|
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
|
||||||
|
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
|
||||||
76
front_end_portserver_old/app/global.css
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--primary: 222.2 47.4% 11.2%;
|
||||||
|
--primary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--secondary: 210 40% 96.1%;
|
||||||
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--muted: 210 40% 96.1%;
|
||||||
|
--muted-foreground: 215.4 16.3% 46.9%;
|
||||||
|
|
||||||
|
--accent: 210 40% 96.1%;
|
||||||
|
--accent-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--border: 214.3 31.8% 91.4%;
|
||||||
|
--input: 214.3 31.8% 91.4%;
|
||||||
|
--ring: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 222.2 84% 4.9%;
|
||||||
|
--foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--card: 222.2 84% 4.9%;
|
||||||
|
--card-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--popover: 222.2 84% 4.9%;
|
||||||
|
--popover-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--primary: 210 40% 98%;
|
||||||
|
--primary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--secondary: 217.2 32.6% 17.5%;
|
||||||
|
--secondary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--muted: 217.2 32.6% 17.5%;
|
||||||
|
--muted-foreground: 215 20.2% 65.1%;
|
||||||
|
|
||||||
|
--accent: 217.2 32.6% 17.5%;
|
||||||
|
--accent-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--border: 217.2 32.6% 17.5%;
|
||||||
|
--input: 217.2 32.6% 17.5%;
|
||||||
|
--ring: 212.7 26.8% 83.9%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
front_end_portserver_old/components.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://ui.shadcn.com/schema.json",
|
||||||
|
"style": "default",
|
||||||
|
"rsc": false,
|
||||||
|
"tsx": true,
|
||||||
|
"tailwind": {
|
||||||
|
"config": "tailwind.config.js",
|
||||||
|
"css": "app/global.css",
|
||||||
|
"baseColor": "slate",
|
||||||
|
"cssVariables": true
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"components": "@/components",
|
||||||
|
"utils": "@/lib/utils"
|
||||||
|
}
|
||||||
|
}
|
||||||
13
front_end_portserver_old/index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + React + TS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
14348
front_end_portserver_old/package-lock.json
generated
Normal file
50
front_end_portserver_old/package.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"name": "front_end_portserver",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc && vite build",
|
||||||
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"storybook": "storybook dev -p 6006",
|
||||||
|
"build-storybook": "storybook build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
"class-variance-authority": "^0.7.0",
|
||||||
|
"clsx": "^2.0.0",
|
||||||
|
"lucide-react": "^0.292.0",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"tailwind-merge": "^2.0.0",
|
||||||
|
"tailwindcss-animate": "^1.0.7"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@storybook/addon-essentials": "^7.5.2",
|
||||||
|
"@storybook/addon-interactions": "^7.5.2",
|
||||||
|
"@storybook/addon-links": "^7.5.2",
|
||||||
|
"@storybook/addon-onboarding": "^1.0.8",
|
||||||
|
"@storybook/blocks": "^7.5.2",
|
||||||
|
"@storybook/react": "^7.5.2",
|
||||||
|
"@storybook/react-vite": "^7.5.2",
|
||||||
|
"@storybook/testing-library": "^0.2.2",
|
||||||
|
"@types/node": "^20.8.10",
|
||||||
|
"@types/react": "^18.2.15",
|
||||||
|
"@types/react-dom": "^18.2.7",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||||
|
"@typescript-eslint/parser": "^6.0.0",
|
||||||
|
"@vitejs/plugin-react": "^4.0.3",
|
||||||
|
"autoprefixer": "^10.4.16",
|
||||||
|
"eslint": "^8.45.0",
|
||||||
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.3",
|
||||||
|
"eslint-plugin-storybook": "^0.6.15",
|
||||||
|
"postcss": "^8.4.31",
|
||||||
|
"storybook": "^7.5.2",
|
||||||
|
"tailwindcss": "^3.3.5",
|
||||||
|
"typescript": "^5.0.2",
|
||||||
|
"vite": "^4.4.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
front_end_portserver_old/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
1
front_end_portserver_old/public/vite.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
42
front_end_portserver_old/src/App.css
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#root {
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 6em;
|
||||||
|
padding: 1.5em;
|
||||||
|
will-change: filter;
|
||||||
|
transition: filter 300ms;
|
||||||
|
}
|
||||||
|
.logo:hover {
|
||||||
|
filter: drop-shadow(0 0 2em #646cffaa);
|
||||||
|
}
|
||||||
|
.logo.react:hover {
|
||||||
|
filter: drop-shadow(0 0 2em #61dafbaa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes logo-spin {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
a:nth-of-type(2) .logo {
|
||||||
|
animation: logo-spin infinite 20s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
38
front_end_portserver_old/src/App.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
import reactLogo from './assets/react.svg'
|
||||||
|
import viteLogo from '/vite.svg'
|
||||||
|
import './App.css'
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const [count, setCount] = useState(0)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<a href="https://vitejs.dev" target="_blank">
|
||||||
|
<img src={viteLogo} className="logo" alt="Vite logo" />
|
||||||
|
</a>
|
||||||
|
<a href="https://react.dev" target="_blank">
|
||||||
|
<img src={reactLogo} className="logo react" alt="React logo" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>Vite + React</h1>
|
||||||
|
<div className="card">
|
||||||
|
<button onClick={() => setCount((count) => count + 1)}>
|
||||||
|
count is {count}
|
||||||
|
</button>
|
||||||
|
<p>
|
||||||
|
Edit <code>src/App.tsx</code> and save to test HMR
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p className="read-the-docs">
|
||||||
|
Click on the Vite and React logos to learn more
|
||||||
|
</p>
|
||||||
|
<h1 className="text-3xl font-bold underline">
|
||||||
|
INI TAILWIND CSS
|
||||||
|
</h1>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
1
front_end_portserver_old/src/assets/react.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 4.0 KiB |
56
front_end_portserver_old/src/components/ui/button.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const buttonVariants = cva(
|
||||||
|
"inline-flex items-center justify-center 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 }
|
||||||
73
front_end_portserver_old/src/index.css
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color-scheme: light dark;
|
||||||
|
color: rgba(255, 255, 255, 0.87);
|
||||||
|
background-color: #242424;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.25s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
border-color: #646cff;
|
||||||
|
}
|
||||||
|
button:focus,
|
||||||
|
button:focus-visible {
|
||||||
|
outline: 4px auto -webkit-focus-ring-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
color: #213547;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #747bff;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
front_end_portserver_old/src/lib/utils.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { type ClassValue, clsx } from "clsx"
|
||||||
|
import { twMerge } from "tailwind-merge"
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs))
|
||||||
|
}
|
||||||
10
front_end_portserver_old/src/main.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom/client'
|
||||||
|
import App from './App.tsx'
|
||||||
|
import './index.css'
|
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
)
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import { StatusTransferv1 } from '@/components/main/cardInstrument/StatusTransferv1';
|
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
|
import { Button } from './Button';
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
||||||
const meta = {
|
const meta = {
|
||||||
title: 'Component/Main/Status Transfer',
|
title: 'Example/Button',
|
||||||
component: StatusTransferv1,
|
component: Button,
|
||||||
parameters: {
|
parameters: {
|
||||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
|
||||||
layout: 'centered',
|
layout: 'centered',
|
||||||
@@ -13,22 +14,37 @@ const meta = {
|
|||||||
tags: ['autodocs'],
|
tags: ['autodocs'],
|
||||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
||||||
argTypes: {
|
argTypes: {
|
||||||
// backgroundColor: { control: 'color' },
|
backgroundColor: { control: 'color' },
|
||||||
},
|
},
|
||||||
} satisfies Meta<typeof StatusTransferv1>;
|
} satisfies Meta<typeof Button>;
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof meta>;
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
||||||
export const StatusTransferTrue: Story = {
|
export const Primary: Story = {
|
||||||
args: {
|
args: {
|
||||||
isTransferCard:true
|
primary: true,
|
||||||
|
label: 'Button',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StatusTransferFalse: Story = {
|
export const Secondary: Story = {
|
||||||
args: {
|
args: {
|
||||||
isTransferCard:false
|
label: 'Button',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Large: Story = {
|
||||||
|
args: {
|
||||||
|
size: 'large',
|
||||||
|
label: 'Button',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Small: Story = {
|
||||||
|
args: {
|
||||||
|
size: 'small',
|
||||||
|
label: 'Button',
|
||||||
|
},
|
||||||
|
};
|
||||||
27
front_end_portserver_old/src/stories/Header.stories.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
|
import { Header } from './Header';
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Example/Header',
|
||||||
|
component: Header,
|
||||||
|
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
|
||||||
|
tags: ['autodocs'],
|
||||||
|
parameters: {
|
||||||
|
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
|
||||||
|
layout: 'fullscreen',
|
||||||
|
},
|
||||||
|
} satisfies Meta<typeof Header>;
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
|
export const LoggedIn: Story = {
|
||||||
|
args: {
|
||||||
|
user: {
|
||||||
|
name: 'Jane Doe',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LoggedOut: Story = {};
|
||||||
29
front_end_portserver_old/src/stories/Page.stories.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { within, userEvent } from '@storybook/testing-library';
|
||||||
|
|
||||||
|
import { Page } from './Page';
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Example/Page',
|
||||||
|
component: Page,
|
||||||
|
parameters: {
|
||||||
|
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
|
||||||
|
layout: 'fullscreen',
|
||||||
|
},
|
||||||
|
} satisfies Meta<typeof Page>;
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
|
export const LoggedOut: Story = {};
|
||||||
|
|
||||||
|
// More on interaction testing: https://storybook.js.org/docs/react/writing-tests/interaction-testing
|
||||||
|
export const LoggedIn: Story = {
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
const loginButton = await canvas.getByRole('button', {
|
||||||
|
name: /Log in/i,
|
||||||
|
});
|
||||||
|
await userEvent.click(loginButton);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 456 KiB After Width: | Height: | Size: 456 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |