forked from cerc-io/snowballtools-base
Merge pull request #150 from snowball-tools/andrehadianto/T-4912-create-project-create-repository-page
[T-4912] create project create repository page
This commit is contained in:
commit
621ca8926e
@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { CustomIcon, CustomIconProps } from './CustomIcon';
|
||||||
|
|
||||||
|
export const LinkChainIcon = (props: CustomIconProps) => {
|
||||||
|
return (
|
||||||
|
<CustomIcon
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M9.75027 5.52371L10.7168 4.55722C13.1264 2.14759 17.0332 2.14759 19.4428 4.55722C21.8524 6.96684 21.8524 10.8736 19.4428 13.2832L18.4742 14.2519M5.52886 9.74513L4.55722 10.7168C2.14759 13.1264 2.1476 17.0332 4.55722 19.4428C6.96684 21.8524 10.8736 21.8524 13.2832 19.4428L14.2478 18.4782M9.5 14.5L14.5 9.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeLinecap="round"
|
||||||
|
/>
|
||||||
|
</CustomIcon>
|
||||||
|
);
|
||||||
|
};
|
@ -40,6 +40,7 @@ export * from './GithubStrokeIcon';
|
|||||||
export * from './BranchStrokeIcon';
|
export * from './BranchStrokeIcon';
|
||||||
export * from './StorageIcon';
|
export * from './StorageIcon';
|
||||||
export * from './LinkIcon';
|
export * from './LinkIcon';
|
||||||
|
export * from './LinkChainIcon';
|
||||||
export * from './CursorBoxIcon';
|
export * from './CursorBoxIcon';
|
||||||
export * from './CommitIcon';
|
export * from './CommitIcon';
|
||||||
export * from './RocketIcon';
|
export * from './RocketIcon';
|
||||||
|
@ -47,15 +47,15 @@ export const Input = ({
|
|||||||
helperIcon: helperIconCls,
|
helperIcon: helperIconCls,
|
||||||
} = inputTheme({ ...styleProps });
|
} = inputTheme({ ...styleProps });
|
||||||
|
|
||||||
const renderLabels = useMemo(
|
const renderLabels = useMemo(() => {
|
||||||
() => (
|
if (!label && !description) return null;
|
||||||
<div className="space-y-1">
|
return (
|
||||||
|
<div className="flex flex-col gap-y-1">
|
||||||
<p className={labelCls()}>{label}</p>
|
<p className={labelCls()}>{label}</p>
|
||||||
<p className={descriptionCls()}>{description}</p>
|
<p className={descriptionCls()}>{description}</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
);
|
||||||
[labelCls, descriptionCls, label, description],
|
}, [labelCls, descriptionCls, label, description]);
|
||||||
);
|
|
||||||
|
|
||||||
const renderLeftIcon = useMemo(() => {
|
const renderLeftIcon = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
@ -73,8 +73,9 @@ export const Input = ({
|
|||||||
);
|
);
|
||||||
}, [cloneIcon, iconCls, iconContainerCls, rightIcon]);
|
}, [cloneIcon, iconCls, iconContainerCls, rightIcon]);
|
||||||
|
|
||||||
const renderHelperText = useMemo(
|
const renderHelperText = useMemo(() => {
|
||||||
() => (
|
if (!helperText) return null;
|
||||||
|
return (
|
||||||
<div className={helperTextCls()}>
|
<div className={helperTextCls()}>
|
||||||
{state &&
|
{state &&
|
||||||
cloneIcon(<WarningIcon className={helperIconCls()} />, {
|
cloneIcon(<WarningIcon className={helperIconCls()} />, {
|
||||||
@ -82,12 +83,11 @@ export const Input = ({
|
|||||||
})}
|
})}
|
||||||
<p>{helperText}</p>
|
<p>{helperText}</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
);
|
||||||
[cloneIcon, state, helperIconCls, helperText, helperTextCls],
|
}, [cloneIcon, state, helperIconCls, helperText, helperTextCls]);
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2 w-full">
|
<div className="flex flex-col gap-y-2">
|
||||||
{renderLabels}
|
{renderLabels}
|
||||||
<div className={containerCls({ class: className })}>
|
<div className={containerCls({ class: className })}>
|
||||||
{leftIcon && renderLeftIcon}
|
{leftIcon && renderLeftIcon}
|
||||||
|
@ -2,7 +2,7 @@ import { VariantProps, tv } from 'tailwind-variants';
|
|||||||
|
|
||||||
export const radioTheme = tv({
|
export const radioTheme = tv({
|
||||||
slots: {
|
slots: {
|
||||||
root: ['flex', 'gap-3', 'flex-wrap'],
|
root: ['flex', 'gap-3'],
|
||||||
wrapper: ['flex', 'items-center', 'gap-2', 'group'],
|
wrapper: ['flex', 'items-center', 'gap-2', 'group'],
|
||||||
label: ['text-sm', 'tracking-[-0.006em]', 'text-elements-high-em'],
|
label: ['text-sm', 'tracking-[-0.006em]', 'text-elements-high-em'],
|
||||||
radio: [
|
radio: [
|
||||||
@ -39,15 +39,34 @@ export const radioTheme = tv({
|
|||||||
'after:data-[state=checked]:group-hover:bg-elements-on-primary',
|
'after:data-[state=checked]:group-hover:bg-elements-on-primary',
|
||||||
'after:data-[state=checked]:group-focus-visible:bg-elements-on-primary',
|
'after:data-[state=checked]:group-focus-visible:bg-elements-on-primary',
|
||||||
],
|
],
|
||||||
|
icon: ['w-[18px]', 'h-[18px]'],
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
orientation: {
|
orientation: {
|
||||||
vertical: { root: ['flex-col'] },
|
vertical: { root: ['flex-col'] },
|
||||||
horizontal: { root: ['flex-row'] },
|
horizontal: { root: ['flex-row'] },
|
||||||
},
|
},
|
||||||
|
variant: {
|
||||||
|
unstyled: {},
|
||||||
|
card: {
|
||||||
|
wrapper: [
|
||||||
|
'px-4',
|
||||||
|
'py-3',
|
||||||
|
'rounded-lg',
|
||||||
|
'border',
|
||||||
|
'border-border-interactive',
|
||||||
|
'bg-controls-tertiary',
|
||||||
|
'shadow-button',
|
||||||
|
'w-full',
|
||||||
|
'cursor-pointer',
|
||||||
|
],
|
||||||
|
label: ['select-none', 'cursor-pointer'],
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
orientation: 'vertical',
|
orientation: 'vertical',
|
||||||
|
variant: 'unstyled',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -49,14 +49,15 @@ export const Radio = ({
|
|||||||
className,
|
className,
|
||||||
options,
|
options,
|
||||||
orientation,
|
orientation,
|
||||||
|
variant,
|
||||||
...props
|
...props
|
||||||
}: RadioProps) => {
|
}: RadioProps) => {
|
||||||
const { root } = radioTheme({ orientation });
|
const { root } = radioTheme({ orientation, variant });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RadixRoot {...props} className={root({ className })}>
|
<RadixRoot {...props} className={root({ className })}>
|
||||||
{options.map((option) => (
|
{options.map((option) => (
|
||||||
<RadioItem key={option.value} {...option} />
|
<RadioItem key={option.value} variant={variant} {...option} />
|
||||||
))}
|
))}
|
||||||
</RadixRoot>
|
</RadixRoot>
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import React, { ComponentPropsWithoutRef } from 'react';
|
import React, { ReactNode, ComponentPropsWithoutRef } from 'react';
|
||||||
import {
|
import {
|
||||||
Item as RadixRadio,
|
Item as RadixRadio,
|
||||||
Indicator as RadixIndicator,
|
Indicator as RadixIndicator,
|
||||||
RadioGroupItemProps,
|
RadioGroupItemProps,
|
||||||
RadioGroupIndicatorProps,
|
RadioGroupIndicatorProps,
|
||||||
} from '@radix-ui/react-radio-group';
|
} from '@radix-ui/react-radio-group';
|
||||||
import { radioTheme } from './Radio.theme';
|
import { RadioTheme, radioTheme } from './Radio.theme';
|
||||||
|
import { cloneIcon } from 'utils/cloneIcon';
|
||||||
|
|
||||||
export interface RadioItemProps extends RadioGroupItemProps {
|
export interface RadioItemProps
|
||||||
|
extends RadioGroupItemProps,
|
||||||
|
Pick<RadioTheme, 'variant'> {
|
||||||
/**
|
/**
|
||||||
* The wrapper props of the radio item.
|
* The wrapper props of the radio item.
|
||||||
* You can use this prop to customize the wrapper props.
|
* You can use this prop to customize the wrapper props.
|
||||||
@ -27,6 +30,10 @@ export interface RadioItemProps extends RadioGroupItemProps {
|
|||||||
* The id of the radio item.
|
* The id of the radio item.
|
||||||
*/
|
*/
|
||||||
id?: string;
|
id?: string;
|
||||||
|
/**
|
||||||
|
* The left icon of the radio item.
|
||||||
|
*/
|
||||||
|
leftIcon?: ReactNode;
|
||||||
/**
|
/**
|
||||||
* The label of the radio item.
|
* The label of the radio item.
|
||||||
*/
|
*/
|
||||||
@ -41,18 +48,29 @@ export const RadioItem = ({
|
|||||||
wrapperProps,
|
wrapperProps,
|
||||||
labelProps,
|
labelProps,
|
||||||
indicatorProps,
|
indicatorProps,
|
||||||
|
leftIcon,
|
||||||
label,
|
label,
|
||||||
id,
|
id,
|
||||||
|
variant,
|
||||||
...props
|
...props
|
||||||
}: RadioItemProps) => {
|
}: RadioItemProps) => {
|
||||||
const { wrapper, label: labelClass, radio, indicator } = radioTheme();
|
const {
|
||||||
|
wrapper,
|
||||||
|
label: labelClass,
|
||||||
|
radio,
|
||||||
|
indicator,
|
||||||
|
icon,
|
||||||
|
} = radioTheme({ variant });
|
||||||
|
|
||||||
// Generate a unique id for the radio item from the label if the id is not provided
|
// Generate a unique id for the radio item from the label if the id is not provided
|
||||||
const kebabCaseLabel = label?.toLowerCase().replace(/\s+/g, '-');
|
const kebabCaseLabel = label?.toLowerCase().replace(/\s+/g, '-');
|
||||||
const componentId = id ?? kebabCaseLabel;
|
const componentId = id ?? kebabCaseLabel;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={wrapper({ className: wrapperProps?.className })}>
|
<label
|
||||||
|
htmlFor={componentId}
|
||||||
|
className={wrapper({ className: wrapperProps?.className })}
|
||||||
|
>
|
||||||
<RadixRadio {...props} className={radio({ className })} id={componentId}>
|
<RadixRadio {...props} className={radio({ className })} id={componentId}>
|
||||||
<RadixIndicator
|
<RadixIndicator
|
||||||
forceMount
|
forceMount
|
||||||
@ -60,15 +78,20 @@ export const RadioItem = ({
|
|||||||
className={indicator({ className: indicatorProps?.className })}
|
className={indicator({ className: indicatorProps?.className })}
|
||||||
/>
|
/>
|
||||||
</RadixRadio>
|
</RadixRadio>
|
||||||
|
{leftIcon && (
|
||||||
|
<span>
|
||||||
|
{cloneIcon(leftIcon, { className: icon(), 'aria-hidden': true })}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
{label && (
|
{label && (
|
||||||
<label
|
<label
|
||||||
{...labelProps}
|
{...labelProps}
|
||||||
className={labelClass({ className: labelProps?.className })}
|
|
||||||
htmlFor={componentId}
|
htmlFor={componentId}
|
||||||
|
className={labelClass({ className: labelProps?.className })}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
</div>
|
</label>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -266,15 +266,15 @@ export const Select = ({
|
|||||||
onClear?.();
|
onClear?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderLabels = useMemo(
|
const renderLabels = useMemo(() => {
|
||||||
() => (
|
if (!label && !description) return null;
|
||||||
<div className="space-y-1">
|
return (
|
||||||
|
<div className="flex flex-col gap-y-1">
|
||||||
<p className={theme.label()}>{label}</p>
|
<p className={theme.label()}>{label}</p>
|
||||||
<p className={theme.description()}>{description}</p>
|
<p className={theme.description()}>{description}</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
);
|
||||||
[theme, label, description],
|
}, [theme, label, description]);
|
||||||
);
|
|
||||||
|
|
||||||
const renderLeftIcon = useMemo(() => {
|
const renderLeftIcon = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
@ -302,8 +302,9 @@ export const Select = ({
|
|||||||
);
|
);
|
||||||
}, [cloneIcon, theme, rightIcon]);
|
}, [cloneIcon, theme, rightIcon]);
|
||||||
|
|
||||||
const renderHelperText = useMemo(
|
const renderHelperText = useMemo(() => {
|
||||||
() => (
|
if (!helperText) return null;
|
||||||
|
return (
|
||||||
<div className={theme.helperText()}>
|
<div className={theme.helperText()}>
|
||||||
{error &&
|
{error &&
|
||||||
cloneIcon(<WarningIcon className={theme.helperIcon()} />, {
|
cloneIcon(<WarningIcon className={theme.helperIcon()} />, {
|
||||||
@ -311,9 +312,8 @@ export const Select = ({
|
|||||||
})}
|
})}
|
||||||
<p>{helperText}</p>
|
<p>{helperText}</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
);
|
||||||
[cloneIcon, error, theme, helperText],
|
}, [cloneIcon, error, theme, helperText]);
|
||||||
);
|
|
||||||
|
|
||||||
const isMultipleHasValue = multiple && selectedItems.length > 0;
|
const isMultipleHasValue = multiple && selectedItems.length > 0;
|
||||||
const isMultipleHasValueButNotSearchable =
|
const isMultipleHasValueButNotSearchable =
|
||||||
|
@ -6,9 +6,13 @@ import {
|
|||||||
useSearchParams,
|
useSearchParams,
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
|
|
||||||
import { Avatar } from '@material-tailwind/react';
|
|
||||||
|
|
||||||
import templates from '../../../../assets/templates';
|
import templates from '../../../../assets/templates';
|
||||||
|
import {
|
||||||
|
LinkChainIcon,
|
||||||
|
TemplateIcon,
|
||||||
|
TemplateIconType,
|
||||||
|
} from 'components/shared/CustomIcon';
|
||||||
|
import { Heading } from 'components/shared/Heading';
|
||||||
import { Steps } from 'components/shared/Steps';
|
import { Steps } from 'components/shared/Steps';
|
||||||
|
|
||||||
// TODO: Set dynamic route for template and load details from DB
|
// TODO: Set dynamic route for template and load details from DB
|
||||||
@ -44,19 +48,24 @@ const CreateWithTemplate = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<div className="flex justify-between w-5/6 my-4 bg-gray-200 rounded-xl p-6 items-center">
|
<div className="flex flex-col lg:flex-row justify-between w-5/6 my-4 bg-base-bg-alternate rounded-xl p-6 gap-3 items-start lg:items-center">
|
||||||
<Avatar variant="rounded" src="/gray.png" placeholder={''} />
|
<div className="flex items-center gap-3">
|
||||||
<div className="grow px-2">{template?.name}</div>
|
<TemplateIcon type={template?.icon as TemplateIconType} size={48} />
|
||||||
|
<Heading className="font-medium">{template?.name}</Heading>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a
|
<a
|
||||||
href={`https://github.com/${template?.repoFullName}`}
|
href={`https://github.com/${template?.repoFullName}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
|
className="flex gap-1.5 items-center text-sm"
|
||||||
>
|
>
|
||||||
^{' '}
|
<LinkChainIcon size={18} />
|
||||||
{Boolean(template?.repoFullName)
|
<span className="underline">
|
||||||
? template?.repoFullName
|
{Boolean(template?.repoFullName)
|
||||||
: 'Template not supported'}
|
? template?.repoFullName
|
||||||
|
: 'Template not supported'}
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
|
import { useForm, SubmitHandler, Controller } from 'react-hook-form';
|
||||||
import { useNavigate, useOutletContext, useParams } from 'react-router-dom';
|
import { useNavigate, useOutletContext, useParams } from 'react-router-dom';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
|
||||||
import { Button, Option, Typography } from '@material-tailwind/react';
|
|
||||||
|
|
||||||
import { useOctokit } from '../../../../../context/OctokitContext';
|
import { useOctokit } from '../../../../../context/OctokitContext';
|
||||||
import { useGQLClient } from '../../../../../context/GQLClientContext';
|
import { useGQLClient } from '../../../../../context/GQLClientContext';
|
||||||
import AsyncSelect from '../../../../../components/shared/AsyncSelect';
|
|
||||||
import { Template } from '../../../../../types';
|
import { Template } from '../../../../../types';
|
||||||
|
import { Heading } from 'components/shared/Heading';
|
||||||
|
import { Input } from 'components/shared/Input';
|
||||||
|
import { Select, SelectOption } from 'components/shared/Select';
|
||||||
|
import { ArrowRightCircleFilledIcon } from 'components/shared/CustomIcon';
|
||||||
|
import { Checkbox } from 'components/shared/Checkbox';
|
||||||
|
import { Button } from 'components/shared/Button';
|
||||||
|
|
||||||
type SubmitRepoValues = {
|
type SubmitRepoValues = {
|
||||||
framework: string;
|
framework: string;
|
||||||
@ -93,7 +96,7 @@ const CreateRepo = () => {
|
|||||||
fetchUserAndOrgs();
|
fetchUserAndOrgs();
|
||||||
}, [octokit]);
|
}, [octokit]);
|
||||||
|
|
||||||
const { register, handleSubmit, control, reset } = useForm<SubmitRepoValues>({
|
const { handleSubmit, control, reset } = useForm<SubmitRepoValues>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
framework: 'React',
|
framework: 'React',
|
||||||
repoName: '',
|
repoName: '',
|
||||||
@ -110,86 +113,67 @@ const CreateRepo = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(submitRepoHandler)}>
|
<form onSubmit={handleSubmit(submitRepoHandler)}>
|
||||||
<div className="mb-2">
|
<div className="flex flex-col gap-4 lg:gap-7 w-full">
|
||||||
<Typography variant="h6" placeholder={''}>
|
|
||||||
Create a repository
|
|
||||||
</Typography>
|
|
||||||
<Typography color="gray" placeholder={''}>
|
|
||||||
The project will be cloned into this repository
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
<div className="mb-2">
|
|
||||||
<h5>Framework</h5>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<label className="inline-flex items-center w-1/2 border rounded-lg p-2">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
{...register('framework')}
|
|
||||||
value="React"
|
|
||||||
className="h-5 w-5 text-indigo-600 rounded"
|
|
||||||
/>
|
|
||||||
<span className="ml-2">^React</span>
|
|
||||||
</label>
|
|
||||||
<label className="inline-flex items-center w-1/2 border rounded-lg p-2">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
{...register('framework')}
|
|
||||||
className="h-5 w-5 text-indigo-600 rounded"
|
|
||||||
value="Next"
|
|
||||||
/>
|
|
||||||
<span className="ml-2">^Next</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mb-2">
|
|
||||||
<h5>Git account</h5>
|
|
||||||
<div>
|
<div>
|
||||||
|
<Heading as="h3" className="text-lg font-medium">
|
||||||
|
Create a repository
|
||||||
|
</Heading>
|
||||||
|
<Heading as="h5" className="text-sm font-sans text-elements-low-em">
|
||||||
|
The project will be cloned into this repository
|
||||||
|
</Heading>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col justify-start gap-3">
|
||||||
|
<span className="text-sm text-elements-high-em">Git account</span>
|
||||||
<Controller
|
<Controller
|
||||||
name="account"
|
name="account"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field: { value, onChange } }) => (
|
||||||
<AsyncSelect {...field}>
|
<Select
|
||||||
{gitAccounts.map((account, key) => (
|
value={{ value } as SelectOption}
|
||||||
<Option key={key} value={account}>
|
onChange={(value) => onChange((value as SelectOption).value)}
|
||||||
^ {account}
|
options={
|
||||||
</Option>
|
gitAccounts.map((account) => ({
|
||||||
))}
|
value: account,
|
||||||
</AsyncSelect>
|
label: account,
|
||||||
|
})) ?? []
|
||||||
|
}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="flex flex-col justify-start gap-3">
|
||||||
<div className="mb-2">
|
<span className="text-sm text-elements-high-em">Name the repo</span>
|
||||||
<h5>Name the repo</h5>
|
<Controller
|
||||||
<div>
|
name="repoName"
|
||||||
<input
|
control={control}
|
||||||
type="text"
|
render={({ field: { value, onChange } }) => (
|
||||||
className="border border-gray-300 rounded p-2 w-full focus:border-blue-300 focus:outline-none focus:shadow-outline-blue"
|
<Input value={value} onChange={onChange} />
|
||||||
placeholder=""
|
)}
|
||||||
{...register('repoName')}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<div className="mb-2">
|
<Controller
|
||||||
<label className="inline-flex items-center">
|
name="isPrivate"
|
||||||
<input
|
control={control}
|
||||||
type="checkbox"
|
render={({ field: { value, onChange } }) => (
|
||||||
className="h-5 w-5 text-indigo-600 rounded"
|
<Checkbox
|
||||||
{...register('isPrivate')}
|
label="Make this repo private"
|
||||||
|
checked={value}
|
||||||
|
onCheckedChange={onChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<span className="ml-2">Make this repo private</span>
|
</div>
|
||||||
</label>
|
<div>
|
||||||
</div>
|
<Button
|
||||||
<div className="mb-2">
|
type="submit"
|
||||||
<Button
|
size="lg"
|
||||||
className="bg-blue-500 rounded-xl p-2"
|
disabled={!Boolean(template.repoFullName) || isLoading}
|
||||||
type="submit"
|
rightIcon={<ArrowRightCircleFilledIcon />}
|
||||||
disabled={!Boolean(template.repoFullName) || isLoading}
|
>
|
||||||
loading={isLoading}
|
Deploy
|
||||||
placeholder={''}
|
</Button>
|
||||||
>
|
</div>
|
||||||
Deploy ^
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user