Completed introductory phase of Astronomy frontend

master
sigonasr2 4 years ago
parent 311da62018
commit c22e7e1ecc
  1. 120
      frontend/package-lock.json
  2. 1
      frontend/package.json
  3. 1
      frontend/public/index.html
  4. 20
      frontend/src/App.css
  5. 201
      frontend/src/App.js
  6. BIN
      frontend/src/backgrounds/stars.png
  7. 144
      server/app.js

@ -1717,6 +1717,11 @@
"csstype": "^2.2.0"
}
},
"@types/react-calendar": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@types/react-calendar/-/react-calendar-3.1.0.tgz",
"integrity": "sha512-Uiygcph3n7Srp/zrufgA3W2NZBYm4wyeVx/VE9f5wgavdRmvfb+Y211UvZJ8iJdvsigTHkvZMHMM/BiFEtjT/g=="
},
"@types/react-dom": {
"version": "16.9.8",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz",
@ -2049,6 +2054,11 @@
"@xtuc/long": "4.2.2"
}
},
"@wojtekmaj/date-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@wojtekmaj/date-utils/-/date-utils-1.0.2.tgz",
"integrity": "sha512-sOu+uH3jzsECLg3YGH++/pLWs8S4eKiXMwMIcotE62CO9AB/HRyhZ0ISwann/30DLnfCw4skvr8h9gF3aafhPA=="
},
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -4414,6 +4424,11 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"detect-element-overflow": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/detect-element-overflow/-/detect-element-overflow-1.2.0.tgz",
"integrity": "sha512-Jtr9ivYPhpd9OJux+hjL0QjUKiS1Ghgy8tvIufUjFslQgIWvgGr4mn57H190APbKkiOmXnmtMI6ytaKzMusecg=="
},
"detect-newline": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
@ -6047,6 +6062,14 @@
"pump": "^3.0.0"
}
},
"get-user-locale": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/get-user-locale/-/get-user-locale-1.4.0.tgz",
"integrity": "sha512-gQo03lP1OArHLKlnoglqrGGl7b04u2EP9Xutmp72cMdtrrSD7ZgIsCsUKZynYWLDkVJW33Cj3pliP7uP0UonHQ==",
"requires": {
"lodash.once": "^4.1.1"
}
},
"get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@ -7911,6 +7934,11 @@
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@ -7995,6 +8023,11 @@
}
}
},
"make-event-props": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.2.0.tgz",
"integrity": "sha512-BmWFkm/jZzVH9A0tEBdkjAARUz/eha+5IRyfOndeSMKRadkgR5DawoBHoRwLxkYmjJOI5bHkXKpaZocxj+dKgg=="
},
"makeerror": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
@ -8092,6 +8125,11 @@
}
}
},
"merge-class-names": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/merge-class-names/-/merge-class-names-1.3.0.tgz",
"integrity": "sha512-k0Qaj36VBpKgdc8c188LEZvo6v/zzry/FUufwopWbMSp6/knfVFU/KIB55/hJjeIpg18IH2WskXJCRnM/1BrdQ=="
},
"merge-deep": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz",
@ -10375,6 +10413,59 @@
"whatwg-fetch": "^3.0.0"
}
},
"react-calendar": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/react-calendar/-/react-calendar-3.1.0.tgz",
"integrity": "sha512-xoKdRe6FrnZ30LD9pyr20fhet1uwSbc6srLGm1ib7G4b7tAXniZrwzrJ4YV/Hbmmwf/zAFGyXtBzLAIV1KNvuA==",
"requires": {
"@wojtekmaj/date-utils": "^1.0.2",
"get-user-locale": "^1.2.0",
"merge-class-names": "^1.1.1",
"prop-types": "^15.6.0"
}
},
"react-clock": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/react-clock/-/react-clock-2.4.0.tgz",
"integrity": "sha512-BlzkzbhLEzLwdqtl+PAPvzMhRvg4xyxsiQnGpb+ZzL4YY5iFQgJa7C48EUGhbpnTtNwyMuaBG4KeYmUuUlTQUQ==",
"requires": {
"merge-class-names": "^1.1.1",
"prop-types": "^15.6.0"
}
},
"react-date-picker": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/react-date-picker/-/react-date-picker-8.0.1.tgz",
"integrity": "sha512-FDM34LTOQ+QoOlsJeKtLZf+11NU2p1hcTy6K1xFgwuvuIwTEpUPJAnyQbgqEbzsHvMVPuNlGJSoSRFbImPWNkw==",
"requires": {
"@types/react-calendar": "^3.0.0",
"@wojtekmaj/date-utils": "^1.0.2",
"get-user-locale": "^1.2.0",
"make-event-props": "^1.1.0",
"merge-class-names": "^1.1.1",
"prop-types": "^15.6.0",
"react-calendar": "^3.0.0",
"react-fit": "^1.0.3",
"update-input-width": "^1.1.1"
}
},
"react-datetime-picker": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/react-datetime-picker/-/react-datetime-picker-3.0.2.tgz",
"integrity": "sha512-ffLjke6JQBa+A01bIHx0zhO3nfPnWWaaijR4O9g0YdaeK4y2BULVbiSY1EiTcKkxMBabchiwnOu3HAjeZat4eA==",
"requires": {
"@wojtekmaj/date-utils": "^1.0.0",
"get-user-locale": "^1.2.0",
"make-event-props": "^1.1.0",
"merge-class-names": "^1.1.1",
"prop-types": "^15.6.0",
"react-calendar": "^3.0.0",
"react-clock": "^2.3.0",
"react-date-picker": "^8.0.0",
"react-fit": "^1.0.3",
"react-time-picker": "^4.0.0"
}
},
"react-dev-utils": {
"version": "10.2.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz",
@ -10592,6 +10683,15 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz",
"integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA=="
},
"react-fit": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/react-fit/-/react-fit-1.2.0.tgz",
"integrity": "sha512-dT6dsaF2cgBeiKsgixzFRgkQK7wp8vjvLdpaVoT+nLx1v+olncOJFBnkK+w83CDHIY6s85DDwYDbkwgHdm8FqA==",
"requires": {
"detect-element-overflow": "^1.2.0",
"prop-types": "^15.6.0"
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -10657,6 +10757,21 @@
"workbox-webpack-plugin": "4.3.1"
}
},
"react-time-picker": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/react-time-picker/-/react-time-picker-4.0.1.tgz",
"integrity": "sha512-qnZDlXXF6AItplelYXMUsHar05VevaYY+SuKIacTZ5YJwyj74ZpScHkolNvcJgo6YYzdX1QC6iNprzcuPHYt7Q==",
"requires": {
"@wojtekmaj/date-utils": "^1.0.0",
"get-user-locale": "^1.2.0",
"make-event-props": "^1.1.0",
"merge-class-names": "^1.1.1",
"prop-types": "^15.6.0",
"react-clock": "^2.3.0",
"react-fit": "^1.0.3",
"update-input-width": "^1.1.1"
}
},
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@ -12651,6 +12766,11 @@
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
},
"update-input-width": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/update-input-width/-/update-input-width-1.2.1.tgz",
"integrity": "sha512-zygDshqDb2C2/kgfoD423n5htv/3OBF7aTaz2u2zZy998EJki8njOHOeZjKEd8XSYeDziIX1JXfMsKaIRJeJ/Q=="
},
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",

@ -8,6 +8,7 @@
"@testing-library/user-event": "^7.2.1",
"axios": "^0.19.2",
"react": "^16.13.1",
"react-datetime-picker": "^3.0.2",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
},

@ -16,6 +16,7 @@
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.

@ -1,6 +1,6 @@
body{
background-color: #0d194a;
background-image: url("http://45.33.13.215/stars.png");
background-image: url("./backgrounds/stars.png");
font-family: Copperplate,Verdana;
color: #fff;
text-shadow:
@ -14,6 +14,11 @@ body{
0 0 30px #ccc;
}
.baseCalendar{
background-color:#6666ff;
color:#fff !important;
}
.starbox{
opacity:0.5;
background-color:#0d194a;
@ -67,6 +72,10 @@ body{
animation-name: fadein;
animation-duration: 4s;
}
.fadein_2 {
animation-name: fadein_2;
animation-duration: 4s;
}
.fadein3 {
animation-name: fadein;
animation-duration: 4s;
@ -88,11 +97,20 @@ body{
0% {opacity:0;}
100% {opacity:1;}
}
@keyframes fadein_2 {
0% {opacity:0;}
100% {opacity:1;}
}
@keyframes slowblink {
0% {opacity:0;}
50% {opacity:1;}
100% {opacity:0;}
}
@keyframes fadeoutin {
0% {opacity:1;}
50% {opacity:0;}
100% {opacity:1;}
}
.stars {
}

@ -2,11 +2,35 @@ import React, {useState,useEffect} from 'react';
import logo from './logo.svg';
import './App.css';
import './fonts/ACROTSRG.TTF'
import './backgrounds/stars.png'
import DateTimePicker from 'react-datetime-picker'
const REMOTE_ADDR = "http://45.33.13.215:3005";
const axios = require('axios');
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return null;
}
const ClickSubmitButton = (input) => {
input.addEventListener("keydown", function(event) {
if (event.keyCode === 13) {
@ -15,17 +39,73 @@ const ClickSubmitButton = (input) => {
});
}
const ChooseFlavorLoadingText = () => {
var strings = [
"Communicating with the celestials...",
"Shooting for the stars...",
"Launching into the heavens...",
"Seeking heavenly advice...",
"Seeking divine wisdom...",
"Determining celestial intersection with the stars...",
"Communicating beyond mortal universes...",
"Heading into a cosmic universe...",
]
return strings[Math.floor(Math.random()*strings.length)]
}
const StartPage = ()=>{
const UserPage = ()=>{
const [text,setText] = useState("");
const [page,setPage] = useState(null);
switch (page) {
default:{
return (<div className="container stars border rounded shadow-sm">
<div className="row">
<div className="col-md-12 header text-center">
<span className="glowHeavy animated fadein">{getCookie("username")}'s ASTRONOMY</span>
</div>
</div>
<div className="row">
<div className="col-md-12 text-center">
{text}
</div>
</div>
</div>);
}
}
}
const StartPage = (p)=>{
const [text,setText] = useState("");
const [loaded,setLoaded] = useState(null);
const [username,setUsername] = useState("");
const [date,setDate] = useState(new Date("Tue Jan 01 1991 00:00:00 GMT+0900"));
const [page,setPage] = useState(null);
const SubmitNewUser = ()=>{
var obj = {username:username,birth_day:date.getDate(),
birth_month:date.getMonth(),birth_year:date.getFullYear(),
birth_minute:date.getMinutes(),birth_hour:date.getHours()}
console.log("Sending request:"+JSON.stringify(obj));
axios.post(REMOTE_ADDR+"/users/add/",obj)
.then((data)=>{
//Next create a cookie to remember this user's data.
console.log("Response: "+data);
for (var keys in obj) {
setCookie(keys,obj[keys],365);
}
//Now refresh the page...
p.setPage("UserPage");
})
}
const SubmitBirthdate = (e)=>{
setPage("LOADING");
SubmitNewUser();
}
const SubmitUsername = (e)=>{
setText(<>
<span className="slowblink">
Communicating with the celestials...
</span></>);
setPage("BIRTHDATE");
}
const UpdateUsername = (e)=>{
setUsername(e.currentTarget.value);
@ -42,24 +122,80 @@ const StartPage = ()=>{
},12000)},[loaded])
useEffect(()=>{setTimeout(()=>{
setText(<><span className="fadein3">Tell me your name...</span>
<br/>
<input type="text" id="username" className="starbox" onChange={(e)=>{UpdateUsername(e)}}/>
<br/>
<button className="starbox" onClick={(e)=>SubmitUsername()} id="submit">Continue</button>
</>);
document.getElementById("username").focus();
ClickSubmitButton(document.getElementById("username"));
},14000)},[loaded])
return (<div className="container stars border rounded shadow-sm">
<div className="row">
<div className="col-md-12 header text-center">
<span className="glowHeavy animated fadein">ASTRONOMY</span>
</div>
</div>
<div className="row">
<div className="col-md-12 text-center">
{text}
</div>
</div>
</div>);
switch (page) {
case "LOADING":{
return(
<div className="pb-3 container stars border rounded shadow-sm">
<div className="row">
<div className="col-md-12 header text-center">
<span className="glowHeavy animated fadein">ASTRONOMY</span>
</div>
</div>
<div className="row">
<div className="col-md-12 text-center">
<span className="slowblink">
{ChooseFlavorLoadingText()}
</span>
</div>
</div>
</div>
);
}break;
case "BIRTHDATE":{
return (
<div className="pb-3 container stars border rounded shadow-sm">
<div className="row">
<div className="col-md-12 header text-center">
<span className="glowHeavy animated fadein">ASTRONOMY</span>
</div>
</div>
<div className="row">
<div className="col-md-12 text-center">
<span className="fadein_2">
I also need to know when you were born. Don't be shy now... Tell it to me, relax.
<br/>
<DateTimePicker
className="glowLight baseCalendar"
autoFocus={true}
onChange={(d)=>{setDate(d);
console.log(d)}}
defaultView={"century"}
value={date}
clearIcon={null}
disableClock={true}
/>
<br/>
<button className="starbox" onClick={(e)=>SubmitBirthdate()} id="submit">Continue</button>
</span>
</div>
</div>
</div>
);
}break;
default:{
return (<div className="pb-3 container stars border rounded shadow-sm">
<div className="row">
<div className="col-md-12 header text-center">
<span className="glowHeavy animated fadein">ASTRONOMY</span>
</div>
</div>
<div className="row">
<div className="col-md-12 text-center">
{text}
</div>
</div>
</div>);
}
}
}
function App() {
@ -68,15 +204,34 @@ function App() {
const [page,setPage] = useState(null);
useEffect(()=>{
axios.get(REMOTE_ADDR)
.then((data)=>{
setData(data.data);
console.log(data);
})
if (getCookie("username")) {
setPage("UserPage");
} else {
setPage("StartPage");
}
},[loaded]);
switch (page) {
/*case "DateTimePicker":{
return <><DateTimePicker
className="glowLight baseCalendar"
autoFocus={true}
onChange={(date)=>{setDate(date);
console.log(date)}}
defaultView={"century"}
value={date}
clearIcon={null}
disableClock={true}
/>
</>
}*/
case "UserPage":{
return <UserPage/>;
}
case "StartPage":{
return <StartPage page={page} setPage={setPage}/>;
}break;
default:{
return <StartPage/>;
return <></>;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

@ -1,8 +1,16 @@
const express = require('express')
const app = express()
const port = 3005
const bodyParser = require('body-parser')
const { json } = require('body-parser')
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
const Pool = require('pg').Pool
app.use(bodyParser.json())
app.use(
bodyParser.urlencoded({
extended: true,
})
)
let allowCrossDomain = function(req, res, next) {
@ -22,14 +30,132 @@ new Pool({
port: 5432,
})
const getUsers = (request, response) => {
pool.query('SELECT * FROM signs', (error, results) => {
if (error) {
response.status(500).json(error.message)
} else {
response.status(200).json(results.rows)
const table_data = [{
name:"users",
required_fields:["username","birth_day","birth_month","birth_year","birth_minute","birth_hour"],
all_fields:["username","birth_day","birth_month","birth_year","birth_minute","birth_hour"]
},{
name:"signs",
required_fields:[],
all_fields:["sign_name","symbol","strengths","weaknesses","element","ruler","jewelry","yinyang"]
},{
name:"compatibility",
required_fields:[],
all_fields:["signId","compatibleSignId"]
},{
name:"numbers",
required_fields:[],
all_fields:["signId","compatibleSignId","compatible"]
},{
name:"colors",
required_fields:[],
all_fields:["signId","color","compatible"]
},{
name:"flowers",
required_fields:[],
all_fields:["signId","flower","compatible"]
},{
name:"directions",
required_fields:[],
all_fields:["signId","direction","compatible"]
}
];
var RequiredFieldsExist = (body,fields) => {
for (var keys of fields) {
if (!(keys in body)) {
return false;
}
}
})
}
return true;
}
var OutputRequiredFieldNames = (required_fields) => required_fields.reduce((result,field)=>(result==="")?result+=field:result+=","+field,"");
var OutputSqlArgumentNumbers = (required_fields) => required_fields.reduce((result,field,count)=>(result==="")?result+="$"+(count+1):result+=","+"$"+(count+1),"");
var OutputBodyData = (body,required_fields) => required_fields.filter((field)=>body[field]!==undefined).map((field)=>body[field]);
var CountFieldNames = (body,all_fields) => {
var counter = 0;
for (var i=0;i<all_fields.length;i++) {
var field = all_fields[i];
if (body[field]) {
counter++;
}
}
return counter;
}
var OutputSqlArgumentsAndFieldNames = (body,all_fields) => {
var finalStr = "";
var count = 0;
for (var i=0;i<all_fields.length;i++) {
var field = all_fields[i];
if (body[field]) {
if (finalStr==="") {
finalStr += field+"=$"+(count+++1)
} else {
finalStr += ","+field+"=$"+(count+++1)
}
}
}
return finalStr;
}
app.get('/', getUsers)
table_data.forEach((table)=>{
app.get("/"+table.name+"/view",(req,res)=>{
pool.query('SELECT * FROM '+table.name+' ORDER BY id ASC', (error, results) => {
if (error) {
throw error
}
res.status(200).json(results.rows)
})
});
app.get("/"+table.name+"/view/:id",(req,res)=>{
pool.query('SELECT * FROM '+table.name+' where id=$1 ORDER BY id ASC', [req.params.id] , (error, results) => {
if (error) {
throw error
}
res.status(200).json(results.rows)
})
});
app.post("/"+table.name+"/add",
(req,res)=>{
if (req.body) {
if (RequiredFieldsExist(req.body,table.required_fields)) {
pool.query('insert into '+table.name+'('+OutputRequiredFieldNames(table.required_fields)+') values('+OutputSqlArgumentNumbers(table.required_fields)+') returning *', OutputBodyData(req.body,table.required_fields) , (error, results) => {
if (error) {
throw error
}
res.status(200).json(results.rows)
})
} else {
res.status(400).json("Missing a field! Required Fields: "+OutputRequiredFieldNames(table.required_fields));
}
}});
app.put("/"+table.name+"/update/:id",
(req,res)=>{
if (req.body && req.params.id && CountFieldNames(req.body,table.all_fields)>0) {
//console.log([...OutputBodyData(req.body,table.all_fields),Number(req.params.id)])
//console.log("update "+table.name+" set "+OutputSqlArgumentsAndFieldNames(req.body,table.all_fields)+" where id=$"+(Object.keys(req.body).length+1)+" returning *")
pool.query("update "+table.name+" set "+OutputSqlArgumentsAndFieldNames(req.body,table.all_fields)+" where id=$"+(CountFieldNames(req.body,table.all_fields)+1)+" returning *", [...OutputBodyData(req.body,table.all_fields),req.params.id] , (error, results) => {
if (error) {
throw error
}
res.status(200).json(results.rows)
})
} else {
res.status(400).json("Missing id or invalid fields! Valid fields are: "+OutputRequiredFieldNames(table.all_fields));
}});
app.delete("/"+table.name+"/delete/:id",
(req,res)=>{
if (req.params.id) {
pool.query("delete from "+table.name+" where id=$1 returning *", [req.params.id] , (error, results) => {
if (error) {
throw error
}
res.status(200).json(results.rows)
})
} else {
res.status(400).json("Missing id!")
}});
})
Loading…
Cancel
Save