diff --git a/src/App.js b/src/App.js
index 39717aa..4b62618 100644
--- a/src/App.js
+++ b/src/App.js
@@ -18,6 +18,7 @@ import { HashLink as Link } from 'react-router-hash-link';
 
 import TestHeader from './TestHeader'; // Test Header!
 import TestPanel from './TestPanel'; // Dudley's Test Panel
+import md5 from 'md5';
 
 const axios = require('axios');
 const parse = require('csv-parse/lib/sync')
@@ -570,11 +571,113 @@ function DamageCalculator(p) {
 	</>
 }
 
+function FormField(p) {
+	return <><label className="formField" for={p.field}>{p.label}</label>{
+		p.type==="toggle"?<><Toggle id={p.field} checked={p.checked} onChange={p.onChange} disabled={p.loading}/> <label className="formDescription" for={p.field}>{p.checked?<b>YES</b>:<b>NO</b>}</label></>:<input type={p.type??"text"} disabled={p.loading} id={p.field} maxlength={p.maxlength} value={p.value} checked={p.checked} onChange={p.onChange} placeholder={p.placeholder}/>} <label className="formDescription" for={p.field}>{p.tooltip}</label></>
+}
+
 function LoginForm(p) {
 	const [username,setUsername] = useState("")
 	const [password,setPassword] = useState("")
 	const [rememberMe,setRememberMe] = useState(false)
-	return <><ExpandTooltip id="tooltip-username" tooltip="Enter a username (4-20 characters, alphanumeric characters only)"><label className="formField" for="username">Username:</label><input id="username" value={username} onChange={(p)=>{setUsername(p.currentTarget.value)}} placeholder="Username"/></ExpandTooltip></>
+	const [error,setError] = useState("")
+	const [loading,setLoading] = useState(false)
+
+	function SubmitLogin() {
+		setError("")
+		setLoading(true)
+		axios.post(GetBackendURL(p)+"/login",{
+			username:username,
+			password:md5(password)
+		})
+		.then((data)=>{
+			if (data.data.verified) {
+				p.setLOGGEDINUSER(username)
+				p.setLOGGEDINHASH(md5(password))
+				setUsername("")
+				setPassword("")
+				setRememberMe(false)
+			} else {
+				setError("Could not authenticate!")
+			}
+		})
+		.catch((err)=>{
+			setError(err?.message??err);
+		})
+		.then(()=>{
+			setLoading(false)
+		})
+	}
+
+	return <>
+	<Box title="Login Form">
+	{loading?
+		<img src={process.env.PUBLIC_URL+"/spinner.gif"} alt="" style={{background:"linear-gradient(white,#bca9f5)",marginTop:"10px"}} />
+		:<><h3 className="formError">{error}</h3>
+		<FormField field="username" label="Username: " value={username} maxlength={20} onChange={(p)=>{setUsername(p.currentTarget.value)}} placeholder="Username"/><br/>
+		<FormField field="password" label="Password: " type="password" value={password} onChange={(p)=>{setPassword(p.currentTarget.value)}} placeholder="Password"/><br/>
+		<FormField field="rememberMe" label="Remember Me " type="toggle" checked={rememberMe} onChange={(p)=>{setRememberMe(p.currentTarget.checked)}}/><br/>
+		<button type="submit" onClick={SubmitLogin}>Login</button></>
+	}
+	</Box></>
+}
+
+function RegisterForm(p) {
+	const [username,setUsername] = useState("")
+	const [password,setPassword] = useState("")
+	const [password2,setPassword2] = useState("")
+	const [rememberMe,setRememberMe] = useState(false)
+	const [error,setError] = useState("")
+	const [loading,setLoading] = useState(false)
+
+	function SubmitRegister() {
+		setError("")
+		setLoading(true)
+		try{
+			if (username.length<4) {throw "Username must be at least 4 characters in length."}
+			if (username.length>20) {throw "Username must be less than 21 characters in length."}
+			if (password.length<6) {throw "Password must contain at least 6 characters."}
+			if (password!==password2) {throw "Password fields must match."}
+		}catch(err){
+			setError(err)
+			setLoading(false)
+			return
+		}
+		axios.post(GetBackendURL(p)+"/register",{
+			username:username,
+			password:md5(password)
+		})
+		.then((data)=>{
+			if (data.data.verified) {
+				p.setLOGGEDINUSER(username)
+				p.setLOGGEDINHASH(md5(password))
+				setUsername("")
+				setPassword("")
+				setRememberMe(false)
+			} else {
+				setError("Could not authenticate!")
+			}
+		})
+		.catch((err)=>{
+			setError(err?.message??err);
+		})
+		.then(()=>{
+			setLoading(false)
+		})
+	}
+
+	return <>
+	<Box title="Registration Form">
+	{loading?
+		<img src={process.env.PUBLIC_URL+"/spinner.gif"} alt="" style={{background:"linear-gradient(white,#bca9f5)",marginTop:"10px"}} />
+		:<><h3 className="formError">{error}</h3>
+		<FormField field="username" label="Username: " value={username} maxlength={20} onChange={(p)=>{setUsername(p.currentTarget.value)}} placeholder="Username" tooltip="Enter a username (4-20 characters, alphanumeric only)"/><br/>
+		<FormField field="password" label="Password: " type="password" value={password} onChange={(p)=>{setPassword(p.currentTarget.value)}} placeholder="Password" tooltip="Enter a password (6 or more characters)"/><br/>
+		<FormField field="password2" label="Verify Password: " type="password" value={password2} onChange={(p)=>{setPassword2(p.currentTarget.value)}} placeholder="Verify Password" tooltip="Enter password again."/><br/>
+		<FormField field="rememberMe" label="Remember Me " type="toggle" checked={rememberMe} onChange={(p)=>{setRememberMe(p.currentTarget.checked)}}/><br/>
+		<button type="submit" onClick={SubmitRegister}>Login</button></>
+	}
+	</Box></>
 }
 
 
@@ -684,14 +787,14 @@ function App() {
 						<title>{APP_TITLE+" - Login"}</title>
 					</Helmet>
 					<TestHeader/>
-					<LoginForm LOGGEDINUSER={LOGGEDINUSER} LOGGEDINHASH={LOGGEDINHASH} setLOGGEDINHASH={setLOGGEDINHASH} setLOGGEDINUSER={setLOGGEDINUSER}/>
+					<LoginForm BACKENDURL={BACKENDURL} TESTMODE={TESTMODE} LOGGEDINUSER={LOGGEDINUSER} LOGGEDINHASH={LOGGEDINHASH} setLOGGEDINHASH={setLOGGEDINHASH} setLOGGEDINUSER={setLOGGEDINUSER}/>
 				</Route>
 				<Route path={process.env.PUBLIC_URL+"/register"}>
 					<Helmet>
 						<title>{APP_TITLE+" - Register"}</title>
 					</Helmet>
 					<TestHeader/>
-					Register form here.
+					<RegisterForm BACKENDURL={BACKENDURL} TESTMODE={TESTMODE} LOGGEDINUSER={LOGGEDINUSER} LOGGEDINHASH={LOGGEDINHASH} setLOGGEDINHASH={setLOGGEDINHASH} setLOGGEDINUSER={setLOGGEDINUSER}/>
 				</Route>
 				<Route path={process.env.PUBLIC_URL+"/formula"}>
 					<DamageCalculator/>
diff --git a/src/components/ExpandTooltip.js b/src/components/ExpandTooltip.js
index 5f5d9c4..0bc5cc1 100644
--- a/src/components/ExpandTooltip.js
+++ b/src/components/ExpandTooltip.js
@@ -1,7 +1,8 @@
 import ReactTooltip from 'react-tooltip' //https://wwayne.github.io/react-tooltip/
 
 function ExpandTooltip(p) {
-	return <><span data-tip data-for={p.id}>{p.children}</span><ReactTooltip id={p.id} className="xTooltip" overridePosition={ (
+
+	return <><span data-tip data-tip-disable={p.tooltip?.length===0} data-for={p.id}>{p.children}</span><ReactTooltip id={p.id} className="xTooltip" overridePosition={ (
     { left, top },
     currentEvent, currentTarget, node) => {
   const d = document.documentElement;
diff --git a/src/style.css b/src/style.css
index e9c2035..5a27107 100644
--- a/src/style.css
+++ b/src/style.css
@@ -1239,4 +1239,11 @@ p.adminNav hr {
 }
 .formField{
 	font-weight:bold;
+}
+.formDescription{
+	font-style:italic;
+}
+.formError{
+	color:red;
+	font-weight:bold;
 }
\ No newline at end of file