Implement domains list in project settings tab (#35)
* Display pending domains card in domain layout * Rename variables * Refactor fields in domains json --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
a6f9e18972
commit
7ba390d59b
@ -1,8 +1,31 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"domainid": 1,
|
"id": 1,
|
||||||
"projectid": 1,
|
"projectid": 1,
|
||||||
"domain": "randomurl.snowballtools.xyz",
|
"name": "randomurl.snowballtools.xyz",
|
||||||
"status": "live"
|
"status": "live",
|
||||||
|
"record": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"projectid": 1,
|
||||||
|
"name": "saugatt.com",
|
||||||
|
"status": "pending",
|
||||||
|
"record": {
|
||||||
|
"type": "A",
|
||||||
|
"name": "@",
|
||||||
|
"value": "56.49.19.21"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"projectid": 1,
|
||||||
|
"name": "www.saugatt.com",
|
||||||
|
"status": "pending",
|
||||||
|
"record": {
|
||||||
|
"type": "CNAME",
|
||||||
|
"name": "www",
|
||||||
|
"value": "cname.snowballtools.xyz"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Chip,
|
Chip,
|
||||||
Typography,
|
Typography,
|
||||||
@ -6,28 +7,55 @@ import {
|
|||||||
MenuHandler,
|
MenuHandler,
|
||||||
MenuList,
|
MenuList,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
|
Card,
|
||||||
} from '@material-tailwind/react';
|
} from '@material-tailwind/react';
|
||||||
|
|
||||||
const DomainCard = (props: { domain: string; status: string }) => {
|
import { DomainDetails, DomainStatus } from '../../../../types/project';
|
||||||
|
|
||||||
|
enum RefreshStatus {
|
||||||
|
IDLE,
|
||||||
|
CHECKING,
|
||||||
|
CHECK_SUCCESS,
|
||||||
|
CHECK_FAIL,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DomainCardProps {
|
||||||
|
domain: DomainDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHECK_FAIL_TIMEOUT = 5000; // In milliseconds
|
||||||
|
|
||||||
|
const DomainCard = ({ domain }: DomainCardProps) => {
|
||||||
|
const [refreshStatus, SetRefreshStatus] = useState(RefreshStatus.IDLE);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex justify-between py-3">
|
<div className="flex justify-between py-3">
|
||||||
<div className="flex justify-start gap-1">
|
<div className="flex justify-start gap-1">
|
||||||
<Typography variant="h6">
|
<Typography variant="h6">
|
||||||
<i>^</i> {props.domain}
|
<i>^</i> {domain.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Chip
|
<Chip
|
||||||
className=" w-fit"
|
className="w-fit capitalize"
|
||||||
value={props.status}
|
value={domain.status}
|
||||||
color="green"
|
color={domain.status === DomainStatus.LIVE ? 'green' : 'orange'}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
icon={<i>^</i>}
|
icon={<i>^</i>}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-start gap-1">
|
<div className="flex justify-start gap-1">
|
||||||
<i id="refresh" className="cursor-pointer w-8 h-8">
|
<i
|
||||||
^
|
id="refresh"
|
||||||
|
className="cursor-pointer w-8 h-8"
|
||||||
|
onClick={() => {
|
||||||
|
SetRefreshStatus(RefreshStatus.CHECKING);
|
||||||
|
setTimeout(() => {
|
||||||
|
SetRefreshStatus(RefreshStatus.CHECK_FAIL);
|
||||||
|
}, CHECK_FAIL_TIMEOUT);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{refreshStatus === RefreshStatus.CHECKING ? 'L' : 'R'}
|
||||||
</i>
|
</i>
|
||||||
<Menu placement="bottom-end">
|
<Menu placement="bottom-end">
|
||||||
<MenuHandler>
|
<MenuHandler>
|
||||||
@ -41,6 +69,44 @@ const DomainCard = (props: { domain: string; status: string }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Typography variant="small">Production</Typography>
|
<Typography variant="small">Production</Typography>
|
||||||
|
{domain.status === DomainStatus.PENDING && (
|
||||||
|
<Card className="bg-gray-200 p-4 text-sm">
|
||||||
|
{refreshStatus === RefreshStatus.IDLE ? (
|
||||||
|
<Typography variant="small">
|
||||||
|
^ Add these records to your domain and refresh to check
|
||||||
|
</Typography>
|
||||||
|
) : refreshStatus === RefreshStatus.CHECKING ? (
|
||||||
|
<Typography variant="small" className="text-blue-500">
|
||||||
|
^ Checking records for {domain.name}
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
|
<div className="flex gap-2 text-red-500 mb-2">
|
||||||
|
<div>^</div>
|
||||||
|
<div className="grow">
|
||||||
|
Failed to verify records. DNS propagation can take up to 48
|
||||||
|
hours. Please ensure you added the correct records and refresh.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-left">Type</th>
|
||||||
|
<th className="text-left">Name</th>
|
||||||
|
<th className="text-left">Value</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{domain.record.type}</td>
|
||||||
|
<td>{domain.record.name}</td>
|
||||||
|
<td>{domain.record.value}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@ import { Button, Typography } from '@material-tailwind/react';
|
|||||||
|
|
||||||
import DomainCard from './DomainCard';
|
import DomainCard from './DomainCard';
|
||||||
import domainsData from '../../../../assets/domains.json';
|
import domainsData from '../../../../assets/domains.json';
|
||||||
|
import { DomainDetails } from '../../../../types/project';
|
||||||
|
|
||||||
const Domains = () => {
|
const Domains = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@ -11,7 +12,7 @@ const Domains = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex justify-between p-2">
|
<div className="flex justify-between p-2">
|
||||||
<Typography variant="h2">Domain</Typography>
|
<Typography variant="h3">Domain</Typography>
|
||||||
<Link to="domain/add">
|
<Link to="domain/add">
|
||||||
<Button color="blue" variant="outlined" className="rounded-full">
|
<Button color="blue" variant="outlined" className="rounded-full">
|
||||||
<i>^</i> Add domain
|
<i>^</i> Add domain
|
||||||
@ -19,18 +20,12 @@ const Domains = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{domainsData
|
{(domainsData as DomainDetails[])
|
||||||
.filter((domain) => {
|
.filter((domain) => {
|
||||||
return Number(id) == domain.projectid;
|
return Number(id) == domain.projectid;
|
||||||
})
|
})
|
||||||
.map((domain) => {
|
.map((domain) => {
|
||||||
return (
|
return <DomainCard domain={domain} key={domain.id} />;
|
||||||
<DomainCard
|
|
||||||
status={domain.status}
|
|
||||||
domain={domain.domain}
|
|
||||||
key={domain.domainid}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -61,3 +61,20 @@ export enum GitSelect {
|
|||||||
GITEA = 'gitea',
|
GITEA = 'gitea',
|
||||||
NONE = 'none',
|
NONE = 'none',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum DomainStatus {
|
||||||
|
LIVE = 'live',
|
||||||
|
PENDING = 'pending',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DomainDetails {
|
||||||
|
id: number;
|
||||||
|
projectid: number;
|
||||||
|
name: string;
|
||||||
|
status: DomainStatus;
|
||||||
|
record: {
|
||||||
|
type: string;
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user