Skip to content
This repository has been archived by the owner on Oct 6, 2021. It is now read-only.

feat: tracer registration page #42

Merged
merged 18 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions __tests__/pages/registration.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { render, screen } from "@testing-library/react";
import RegistrationPage from "~/pages/registration";

jest.mock("next/router", () => require("next-router-mock"));

describe("RegistrationPage", () => {
it("renders correctly", () => {
render(<RegistrationPage />);

const title = screen.getByText(/Pendaftaran Tracer/i);
expect(title).toBeVisible();

const subtitle = screen.getByText(/Isi dengan lengkap dan ingat Nama ID dan Kata Sandi Anda/i);
expect(subtitle).toBeVisible();

const registerButton = screen.getByRole("button", { name: /daftar/i });
expect(registerButton).toBeVisible();
});
});
143 changes: 143 additions & 0 deletions components/registration/registration-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React from "react";
import { InformationCircleIcon, EyeIcon } from "@heroicons/react/outline";

import {
FormGroup,
FormLabel,
InputCheckboxCustom,
InputText,
InputSelect,
} from "~/components/ui/forms";
import { PrimaryButton as Button } from "~/components/ui/button";

export function RegistrationForm() {
return (
<div className="space-y-6">
<div className="space-y-2">
<FormLabel>Nama Lengkap</FormLabel>
<InputText />
</div>
<div className="space-y-2">
<FormLabel>Nomor Whatsapp yang aktif</FormLabel>
<FormGroup>
<span className="inline-flex items-center px-3 first:rounded-l-md last:rounded-r-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm">
+62
</span>
<InputText
className="block w-full sm:text-sm"
isGroupItem
placeholder="838xxxxxxx"
type="text"
/>
</FormGroup>
</div>
<div className="space-y-2">
<FormLabel>Provinsi</FormLabel>
<InputSelect defaultValue="" title="Urut berdasarkan">
<option disabled hidden value="">
-Masukkan Provinsi-
</option>
<option>A</option>
<option>B</option>
<option>C</option>
</InputSelect>
</div>
<div className="space-y-2">
<FormLabel>Kabupaten</FormLabel>
<InputSelect defaultValue="" title="Urut berdasarkan">
<option disabled hidden value="">
-Masukkan Kabupaten-
</option>
<option>A</option>
<option>B</option>
<option>C</option>
</InputSelect>
</div>
<div className="space-y-2">
<FormLabel>Kecamatan</FormLabel>
<InputSelect defaultValue="" title="Urut berdasarkan">
<option disabled hidden value="">
-Masukkan Kecamatan-
</option>
<option>A</option>
<option>B</option>
<option>C</option>
</InputSelect>
</div>
<div className="space-y-2">
<FormLabel>PKM</FormLabel>
<InputSelect defaultValue="" title="Urut berdasarkan">
<option disabled hidden value="">
-Masukkan PKM-
</option>
<option>A</option>
<option>B</option>
<option>C</option>
</InputSelect>
</div>
<div className="space-y-2">
<FormLabel>Instansi Asal</FormLabel>
<div>
<InputCheckboxCustom className="mr-4 w-3/12" name="instance">
TNI
</InputCheckboxCustom>
<InputCheckboxCustom className="mr-4 w-3/12" name="instance">
Polri
</InputCheckboxCustom>
<InputCheckboxCustom className="w-3/12" name="instance">
Puskesmas
</InputCheckboxCustom>
</div>
</div>
<div className="space-y-2">
<FormLabel>Nama ID / Username</FormLabel>
<div className="text-red-500 italic text-sm">
<div className="flex">
<div className="mr-1">
<InformationCircleIcon className="w-5 h-5" />
</div>
<span>
<strong>Nama ID</strong> ini akan digunakan untuk login. Harap di ingat!
</span>
</div>
</div>
<InputText placeholder="Masukkan Nama ID" />
<span className="block text-gray-500">* Tidak Boleh ada spasi minimal 5 karakter</span>
</div>
<div className="space-y-2">
<FormLabel>Kata Sandi / Password</FormLabel>
<div className="text-red-500 italic text-sm">
<div className="flex">
<div className="mr-1">
<InformationCircleIcon className="w-5 h-5" />
</div>
<div>
<strong>Kata Sandi</strong> ini akan digunakan untuk login. Harap di ingat!
</div>
</div>
</div>
<div className="relative rounded-md shadow-sm">
<InputText hasTrailingIcon placeholder="Masukkan Kata Sandi" type="password" />
<div className="absolute inset-y-0 right-0 flex items-center">
<button
className="focus:ring-silacak-500 focus:border-silacak-500 h-full py-0 pl-2 pr-3 border-transparent bg-transparent text-gray-500 sm:text-sm rounded-md"
type="button"
>
<span className="sr-only">Tunjukkan / Sembunyikan Sandi</span>
<EyeIcon aria-hidden className="w-5 h-5 text-silacak-500" />
</button>
</div>
</div>
<span className="block text-gray-500">* Tidak Boleh ada spasi minimal 5 karakter</span>
</div>
<div className="space-y-4">
<p>
Tekan tombol <strong>Daftar</strong> untuk melanjutkan proses pendaftaran.
</p>
<Button block={true} className="w-full uppercase">
Daftar
</Button>
</div>
</div>
);
}
17 changes: 17 additions & 0 deletions components/registration/registration-info-message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";

export function RegistrationInfoMessage() {
return (
<div className="bg-green-100 p-3 border-l-4 border-green-500">
<div>
Mengalami kesulitan?{" "}
<a className="text-green-500 underline" href="#">
Hubungi Help Desk
</a>
</div>
<em>
Jam Operasional Helpdesk <strong>08:00 - 17:00</strong> WIB
</em>
</div>
);
}
21 changes: 21 additions & 0 deletions components/ui/board/content-board-subtitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from "react";
import clsx from "clsx";

export type ContentBoardSubtitleProps = React.ComponentPropsWithoutRef<"h2">;

/**
* Subtitle used to label a form. This is to be used in conjunction with FormTitle.
* @param props
* @constructor
*/
export const ContentBoardSubtitle = React.forwardRef<HTMLHeadingElement, ContentBoardSubtitleProps>(
({ children, className, ...rest }, ref) => {
return (
<h2 className={clsx("text-center text-gray-700", className)} ref={ref} {...rest}>
{children}
</h2>
);
}
);

ContentBoardSubtitle.displayName = "ContentBoardSubtitle";
28 changes: 28 additions & 0 deletions components/ui/board/content-board-title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from "react";
import clsx from "clsx";

export type ContentBoardTitleProps = React.ComponentPropsWithoutRef<"h1">;

/**
* Title element used to label a form.
* @param props
* @constructor
*/
export const ContentBoardTitle = React.forwardRef<HTMLHeadingElement, ContentBoardTitleProps>(
({ children, className, ...rest }, ref) => {
return (
<h1
className={clsx(
"form-title text-2xl uppercase text-center text-silacak-500 font-medium",
className
)}
ref={ref}
{...rest}
>
{children}
</h1>
);
}
);

ContentBoardTitle.displayName = "ContentBoardTitle";
29 changes: 29 additions & 0 deletions components/ui/board/content-board.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from "react";
import clsx from "clsx";

export type ContentBoardProps = React.ComponentPropsWithoutRef<"div">;

/**
* Display a white content board that can contains any content
* Note: By default, the board is not padded.
* @param props
* @constructor
*/
export const ContentBoard = React.forwardRef<HTMLDivElement, ContentBoardProps>(
({ children, className, ...rest }, ref) => {
return (
<div
className={clsx(
"content-board mx-auto max-w-2xl w-full bg-white border rounded-md border-gray-300",
className
)}
ref={ref}
{...rest}
>
{children}
</div>
);
}
);

ContentBoard.displayName = "ContentBoard";
2 changes: 2 additions & 0 deletions components/ui/button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./primary-button";
export * from "./utils";
67 changes: 67 additions & 0 deletions components/ui/button/primary-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as React from "react";

import clsx from "clsx";
import { Spinner } from "../spinner";
import {
buttonBlockStyles,
ButtonProps,
buttonRoundedStyles,
buttonSizes,
disabledStyles,
primaryButtonColors,
renderButtonIcon,
} from "./utils";

/**
* Button component used for primary actions.
*
* @link https://tailwindui.com/components/application-ui/elements/buttons#component-80fd0d5ac7982f1a83b171bb0fb9e116
*/
export const PrimaryButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{
className,
style,
type,
block,
size = "md",
color = "green",
rounded,
icon,
iconPosition = "left",
isLoading,
loadingText = "Memuat...",
disabled,
children,
...rest
},
ref
) => (
<button
className={clsx(
buttonBlockStyles(block, iconPosition),
buttonSizes(size),
buttonRoundedStyles(rounded, size),
"items-center justify-center border border-transparent font-medium shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2",
primaryButtonColors(color),
disabledStyles,
className
)}
disabled={isLoading ?? disabled}
ref={ref}
style={style}
type={type ?? "button"}
{...rest}
>
{renderButtonIcon({
icon: isLoading ? Spinner : icon,
size,
additionalClasses: isLoading ? "animate-spin" : undefined,
iconPosition,
})}
{isLoading ? loadingText : children}
</button>
)
);

PrimaryButton.displayName = "PrimaryButton";
Loading