dashboard fixes
This commit is contained in:
parent
517f9bffe7
commit
35dd581969
|
@ -7,7 +7,7 @@ import './CreateCruisePage.css';
|
|||
|
||||
export default function CreateCruisePage() {
|
||||
const [page, setPage] = useState('info');
|
||||
const [strat, setStrat] = useState<'raw-html' | 'react-js'>('raw-html');
|
||||
const [strat, setStrat] = useState<'raw-html' | 'react-js' | 'raw-html-anthracite' | 'docker' | 'default'>('default');
|
||||
const [owner, setOwner] = useState('');
|
||||
const [repo, setRepo] = useState('');
|
||||
const [name, setName] = useState('');
|
||||
|
@ -32,8 +32,8 @@ export default function CreateCruisePage() {
|
|||
"serviceName": name,
|
||||
"containerUrl": `ghcr.io/${owner}/${repo}`,
|
||||
"namespaceId": search.get("namespaceId"),
|
||||
"serviceUrl": hostUriInput,
|
||||
"hostnammes": []
|
||||
"serviceUrl": "https://"+hostUriInput,
|
||||
"hostnames": []
|
||||
})
|
||||
}).then((response)=> {
|
||||
if(response.status === 200) {
|
||||
|
@ -84,10 +84,13 @@ export default function CreateCruisePage() {
|
|||
|
||||
<input value={name} onChange={(e)=>{setName(e.currentTarget.value)}}/>
|
||||
|
||||
<h5 className={"label-text"}>How did you create your website?</h5>
|
||||
<h5 className={"label-text"}>Choose a Dockerfile template</h5>
|
||||
<p className={"help-text"}>Don't see your technology/framework? Email me: <a href={"mailto:nws-support@nickorlow.com"}>nws-support@nickorlow.com</a></p>
|
||||
<select value={strat}>
|
||||
<option id={"raw-html"} onClick={()=>setStrat('raw-html')}>Raw HTML</option>
|
||||
<select>
|
||||
<option hidden>Select a template</option>
|
||||
<option id={"raw-html"} onClick={()=>setStrat('docker')}>I already have a Dockerfile in the root of my repository</option>
|
||||
<option id={"raw-html"} onClick={()=>setStrat('raw-html-anthracite')}>Raw HTML (with Anthracite Web Server, created by Nick)</option>
|
||||
<option id={"raw-html"} onClick={()=>setStrat('raw-html')}>Raw HTML (with NGINX)</option>
|
||||
<option id={"react-js"} onClick={()=>setStrat('react-js')}>React JS</option>
|
||||
</select>
|
||||
|
||||
|
@ -113,7 +116,7 @@ export default function CreateCruisePage() {
|
|||
setRepo(git_url.pathname.split('/')[2])
|
||||
}
|
||||
} catch (e) {
|
||||
alert('invalid github url')
|
||||
alert('Invalid GitHub URL. Should be of format https://github.com/owner/repo')
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -121,7 +124,7 @@ export default function CreateCruisePage() {
|
|||
try {
|
||||
let url = new URL("https://"+hostUriInput);
|
||||
} catch (e) {
|
||||
alert('invalid host url')
|
||||
alert('Invalid domain! Should be format subdomain.domain.tld. Don\'t include protocols in front (i.e https://)')
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -138,10 +141,11 @@ export default function CreateCruisePage() {
|
|||
page === 'scriptgen' &&
|
||||
<div>
|
||||
<h4>Copy & Paste the below into your terminal to add NWS deployment scripts to your webapp</h4>
|
||||
<code lang={"shell"} style={{backgroundColor: "black", padding: 5, borderRadius: 10}}>
|
||||
<code lang={"shell"} style={{backgroundColor: "#bbbbbb", padding: 5, borderRadius: 10}}>
|
||||
curl -s https://raw.githubusercontent.com/nickorlow/nws-ghactions-templates/main/add-nws.sh | bash -s {strat} {owner} {repo}
|
||||
</code>
|
||||
<br/><span>Ensure the script finishes running before continuing</span>
|
||||
<br/><span>For your security, you may view the source code of the script <a href="https://github.com/nickorlow/nws-ghactions-templates/blob/main/add-nws.sh" target="_blank">here</a></span>
|
||||
<br/>
|
||||
|
||||
<button onClick={()=>setPage('framework-hostname')}>Back</button>
|
||||
|
@ -173,7 +177,7 @@ export default function CreateCruisePage() {
|
|||
new URI("https://"+hostUriInput).subdomain().length > 0 &&
|
||||
<div>
|
||||
<p>Type: CNAME</p>
|
||||
<p>Name: {new URI(hostUriInput).subdomain()} ({new URI(hostUriInput).hostname()})</p>
|
||||
<p>Name: {new URI("https://"+hostUriInput).subdomain()} ({new URI("https://"+hostUriInput).hostname()})</p>
|
||||
<p>Value: entry.nws.nickorlow.com</p>
|
||||
</div>
|
||||
}
|
||||
|
@ -184,9 +188,22 @@ export default function CreateCruisePage() {
|
|||
{
|
||||
page === 'done' &&
|
||||
<div>
|
||||
<h3>Welcome to NWS</h3> <br/>
|
||||
<h3>Welcome to NWS!</h3> <br/>
|
||||
<p>Your site should be avaliable on NWS momentairly</p> <br/>
|
||||
<p>It would be great if you could add the following to your website:</p><br/>
|
||||
<code lang={"html"} style={{ backgroundColor: "#bbbbbb", padding: 5, borderRadius: 10 }}>
|
||||
<p>Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
||||
</code> <br/> <br/>
|
||||
{ strat === "raw-html-anthracite" &&
|
||||
<div>
|
||||
<p>It would be great if you could add the following to your website as well:</p><br/>
|
||||
<code lang={"html"} style={{ backgroundColor: "#bbbbbb", padding: 5, borderRadius: 10 }}>
|
||||
<p>Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
||||
</code> <br/> <br/>
|
||||
</div>
|
||||
|
||||
}
|
||||
<button onClick={()=>{window.location.href="/dashboard"}}>Go to Dashboard</button> <br/>
|
||||
<button onClick={()=>{window.location.href=hostUriInput}}>See my Site</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -4,9 +4,13 @@ import {
|
|||
useGetAccountServices,
|
||||
useGetServicesInNamespace,
|
||||
useLoggedInRedirect,
|
||||
useNWSAccount
|
||||
useNWSAccount,
|
||||
useNWSAuthKey
|
||||
} from "../nws-api/hooks";
|
||||
import {useState} from "react";
|
||||
import {
|
||||
createNamespace
|
||||
} from "../nws-api/calls"
|
||||
import {useState, useEffect} from "react";
|
||||
import {enableSSL} from "../nws-api/calls";
|
||||
|
||||
|
||||
|
@ -16,25 +20,60 @@ export default function DashboardPage() {
|
|||
let {setNs, services, ns} = useGetServicesInNamespace();
|
||||
let namespaces: Namespace[] = useGetAccountNamespaces();
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
return(
|
||||
<div style={{minHeight: "100vh", padding: "50px"}}>
|
||||
<div className={"row"}>
|
||||
<p>I don't really know what I was on when I wrote this but a lot of things in the web ui are goofy, sorry about that.. :/ A new one is on its way.</p>
|
||||
<h1 className={"col-md-10 col-12"}>Welcome to NWS, {account?.name}!</h1>
|
||||
<select className={"col-12 col-md-2"} defaultValue={"Select Namespace..."}>
|
||||
<option value="" disabled selected>Select Namespace...</option>
|
||||
{
|
||||
namespaces.map((e)=>{
|
||||
return <option onClick={(a)=>{setNs(e)}}>{e.name}</option>
|
||||
})
|
||||
}
|
||||
<option value="" disabled>---</option>
|
||||
<option value="create-ns">Create Namespace</option>
|
||||
</select>
|
||||
<div className={"col-12 col-md-2"}>
|
||||
<p>Namespace</p>
|
||||
<select className="w-100">
|
||||
<option value="" disabled selected={!urlParams.has('namespace')}>Select Namespace...</option>
|
||||
{
|
||||
namespaces.map((e)=>{
|
||||
if (urlParams.get('namespace') === e.id && ns?.id != e.id)
|
||||
setNs(e);
|
||||
return <option onClick={(a)=>{
|
||||
const url = new URL(window.location.toString());
|
||||
url.searchParams.set('namespace', e.id);
|
||||
window.history.pushState(null, '', url.toString());
|
||||
setNs(e);
|
||||
}} selected={urlParams.get('namespace') === e.id}>{e.name}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<div>
|
||||
<button className="w-100 p-0 mt-2" onClick={async () => {
|
||||
let name = prompt("Enter a name for the namespace");
|
||||
let rawSession: string | null = localStorage.getItem("session_key");
|
||||
|
||||
if (rawSession != null) {
|
||||
let session: SessionKey = JSON.parse(rawSession);
|
||||
let newNamespace = await createNamespace(name!, account!.id!, session);
|
||||
const url = new URL(window.location.toString());
|
||||
url.searchParams.set('namespace', newNamespace.id);
|
||||
window.history.pushState(null, '', url.toString());
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert("Error creating namespace");
|
||||
}
|
||||
}}>
|
||||
Create Namespace
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div className={"d-flex justify-content-between"}>
|
||||
<h2>Container Deployment Services</h2>
|
||||
<button onClick={(e) => {window.location.href = "/cruise/new?namespaceId="+ns!.id}}>Create Cruise Service</button>
|
||||
<button onClick={(e) => {
|
||||
if (ns != null)
|
||||
window.location.href = "/cruise/new?namespaceId="+ns!.id
|
||||
else
|
||||
alert("Please select a namespace!")
|
||||
}}>Create Container Deployment</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
|
||||
|
@ -47,16 +86,19 @@ export default function DashboardPage() {
|
|||
<p>{e.serviceId}</p>
|
||||
{e.hostnames.map((host)=>{
|
||||
return (
|
||||
<div className={"mb-2 p-2"}>
|
||||
<a href={host.hostname}>{host.hostname}</a>
|
||||
{!host.isSslEnabled ? <a onClick={async () => {
|
||||
<div className={"mb-2 p-2 d-flex justify-content-between"}>
|
||||
<a href={"http://"+host.hostname}>{host.hostname}</a>
|
||||
{!host.isSslEnabled ? <div><button onClick={async () => {
|
||||
let rawSession: string | null = localStorage.getItem("session_key");
|
||||
|
||||
if (rawSession != null) {
|
||||
let session: SessionKey = JSON.parse(rawSession);
|
||||
await enableSSL(account!.id!, e.serviceId, host.hostname, session);
|
||||
alert(`SSL has been enabled on the hostname ${host.hostname}. It should be ready in 2-5 minutes.`);
|
||||
// hack but whatever
|
||||
window.location.reload();
|
||||
}
|
||||
}}>Enable SSL</a> : <p>SSL is enabled!</p>
|
||||
}}>Enable SSL</button></div> : <p>SSL is enabled!</p>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ import React from "react";
|
|||
export default function Footer() {
|
||||
return (
|
||||
<footer className={"mt-2 p-3"} style={{backgroundColor: "#eee"}}>
|
||||
<p>NWS is owned and operated by <a href={"http://nickorlow.com"}>Nicholas Orlowsky</a>.</p>
|
||||
<p>SMC is owned and operated by <a href={"http://nickorlow.com"}>Nicholas Orlowsky</a>.</p>
|
||||
<p>Copyright © Nicholas Orlowsky {new Date().getFullYear()}</p>
|
||||
</footer>
|
||||
);
|
||||
|
|
|
@ -37,18 +37,15 @@ export default function HomePage() {
|
|||
<img src={NWSLogo} alt="nws-logo" style={{width: "70%"}}/>
|
||||
</div>
|
||||
<div className={"col-md-6 text-center d-flex justify-content-center flex-column align-items-center"}>
|
||||
<h1>Nick Web Services</h1>
|
||||
<p style={{maxWidth: 500}} className={"col-md-6 text-center"}>
|
||||
Nick Web Services is a hosting service based out of
|
||||
Austin, Texas. It is committed
|
||||
to achieving maximum uptime with better performance and a lower cost than any of the major cloud
|
||||
services.
|
||||
<h1>Sharpe Mountain Compute</h1>
|
||||
<p className={"col-md-6 text-center"}>
|
||||
Sharpe Mountain Compute (fka Nick Web Services) is a reliable cloud compute provider. SMC is dedicated to achieving maximum uptime at a lower cost than traditional cloud compute providers.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"w-100 mt-2 flex justify-content-center align-content-center text-center"}>
|
||||
<h3><i>100% Uptime from 1/1/2023 - 11/8/2023</i></h3>
|
||||
<h4><a href={"https://youtu.be/WHdXWMFHuqA"} target="_blank" rel="noopener noreferrer">Watch the NWS Deployment Demo</a></h4>
|
||||
<h4><a href={"https://youtu.be/WHdXWMFHuqA"} target="_blank" rel="noopener noreferrer">Watch the SMC Deployment Demo</a></h4>
|
||||
</div>
|
||||
<div style={{width: '75vw'}}>
|
||||
<hr/>
|
||||
|
|
|
@ -96,9 +96,9 @@ export default function RegisterPage() {
|
|||
</div>
|
||||
|
||||
<div className={"reg-box"} style={{display: didRegister ? "flex" : "none"}}>
|
||||
<h3>Verify your E-Mail address.</h3>
|
||||
<h3>Successfully Registered!</h3>
|
||||
|
||||
<p>Please verify your E-Mail by clicking the link we sent to you at: <b>{email}</b></p>
|
||||
<p><a href="/login">Proceed to login</a></p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -38,22 +38,22 @@ export default function UptimeComparisonCard(props: {uptime: UptimeRecord, isSer
|
|||
</div>
|
||||
<hr className={" w-100"}/>
|
||||
<p className={"fw-bold d-lg-none"}>Uptime (Last Month)</p>
|
||||
<div style={{height: 25, margin: 0}} className={"pt-2 pt-lg-0"}>
|
||||
<div style={{height: 25, margin: 0}} className={"pb-2 pt-lg-0"}>
|
||||
<p className={getUptimeClass(props.uptime.uptimeMonth)}>{props.uptime.uptimeMonth}%</p>
|
||||
</div>
|
||||
<hr className={"d-lg-block d-none w-100"}/>
|
||||
<p className={"fw-bold d-lg-none"}>Uptime ({new Date().getFullYear()} YTD)</p>
|
||||
<div style={{height: 25, margin: 0}} className={"pt-2 pt-lg-0"}>
|
||||
<div style={{height: 25, margin: 0}} className={"pb-2 pt-lg-0"}>
|
||||
<p className={getUptimeClass(props.uptime.uptimeYtd)}>{props.uptime.uptimeYtd}%</p>
|
||||
</div>
|
||||
<hr className={"d-lg-block d-none w-100"}/>
|
||||
<p className={"fw-bold d-lg-none"}>Avg Response Time (24hr)</p>
|
||||
<div style={{height: 25, margin: 0}} className={"pt-2 pt-lg-0"}>
|
||||
<div style={{height: 25, margin: 0}} className={"pb-2 pt-lg-0"}>
|
||||
<p className={getResponseTimeClass(props.uptime.averageResponseTime)}>{props.uptime.averageResponseTime}ms</p>
|
||||
</div>
|
||||
<hr className={"d-lg-block d-none w-100"} />
|
||||
<p className={"fw-bold d-lg-none"}>Current Status</p>
|
||||
<div style={{height: 25, margin: 0}} className={"pt-2 pt-lg-0"}>
|
||||
<div style={{height: 25, margin: 0}} className={"pb-2 pt-lg-0"}>
|
||||
|
||||
<div className={`p-1 d-flex justify-content-start w-100`} >
|
||||
<p className={`fw-bold severity-label w-100
|
||||
|
|
|
@ -28,7 +28,7 @@ function Layout (props: {children: any}) {
|
|||
<div>
|
||||
<header className={"w-100 sticky-top"}>
|
||||
<div className={"w-100"}>
|
||||
<Navbar sticky={"top"} expand="lg" className={"row justify-content-center m-0 p-0"} style={{backgroundColor: "#eee"}}>
|
||||
<Navbar sticky={"top"} expand="md" className={"row justify-content-center m-0 p-0"} style={{backgroundColor: "#eee"}}>
|
||||
<div className={"row w-100"}>
|
||||
<div className="row w-100 d-md-none d-sm-block">
|
||||
<div className={"col-9"}>
|
||||
|
|
|
@ -50,6 +50,22 @@ export async function getNamespaces(accountId: string, skey: SessionKey): Promis
|
|||
return namespaces;
|
||||
}
|
||||
|
||||
export async function createNamespace(name: string, accountId: string, session: SessionKey): Promise<Namespace> {
|
||||
let response: Response = await fetch('https://api-nws.nickorlow.com/namespaces', {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: btoa(session.accountId + ":" + session.id)
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
'name': name,
|
||||
'ownerId': accountId
|
||||
})
|
||||
});
|
||||
let namespace: Namespace = await response.json();
|
||||
return namespace;
|
||||
}
|
||||
|
||||
export async function enableSSL(accountId: string, serviceId: string, hostname: string, session: SessionKey) {
|
||||
await fetch('https://api-nws.nickorlow.com/'+accountId+'/service/'+serviceId+"/hosts/"+hostname+"/ssl", {
|
||||
headers: {
|
||||
|
|
Loading…
Reference in a new issue