working on droplet, adding app components
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -5,3 +5,8 @@ node_modules
|
||||
|
||||
db/db.json
|
||||
ui/_/code/env.js
|
||||
apps/*
|
||||
|
||||
csv.csv
|
||||
csv.js
|
||||
csv.json
|
||||
@@ -5,6 +5,9 @@
|
||||
"scripts": {
|
||||
"start": "node server/index.js"
|
||||
},
|
||||
"workspaces": [
|
||||
"apps/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"argon2": "^0.44.0",
|
||||
"chalk": "^4.1.2",
|
||||
|
||||
@@ -17,12 +17,14 @@ import Database from "./db/db.js"
|
||||
import AuthHandler from './auth.js';
|
||||
import PaymentsHandler from "./payments.js"
|
||||
|
||||
import parchment from '../apps/parchment/index.js';
|
||||
|
||||
class Server {
|
||||
db;
|
||||
auth;
|
||||
UIPath = path.join(__dirname, '../ui')
|
||||
DBPath = path.join(__dirname, '../db')
|
||||
ComalPath = path.join(os.homedir(), 'Sites/comalyr.com')
|
||||
ComalPath = path.join(os.homedir(), 'comalyr.com')
|
||||
|
||||
registerRoutes(router) {
|
||||
/* Stripe */
|
||||
@@ -75,7 +77,7 @@ class Server {
|
||||
const contact = contactRaw.trim() ? JSON.parse(contactRaw) : [];
|
||||
const members = db.members.getByNetwork(networkId)
|
||||
let stripeMembers = await payments.getCustomers(networkId)
|
||||
console.log("stripemenbers: ", stripeMembers)
|
||||
// console.log("stripemenbers: ", stripeMembers)
|
||||
|
||||
res.json({
|
||||
join,
|
||||
@@ -263,6 +265,8 @@ class Server {
|
||||
app.use(this.logRequest);
|
||||
app.use(this.logResponse);
|
||||
|
||||
app.use('/apps/parchment', parchment.app);
|
||||
|
||||
let router = express.Router();
|
||||
this.registerRoutes(router)
|
||||
app.use('/', router);
|
||||
|
||||
@@ -56,7 +56,6 @@ export default class PaymentsHandler {
|
||||
{ limit: 100, expand: ['data.subscriptions'] },
|
||||
{ stripeAccount: network.stripeAccountId }
|
||||
);
|
||||
console.log(customers)
|
||||
|
||||
return customers.data.map(customer => ({
|
||||
id: customer.id,
|
||||
|
||||
56
serveradmin.md
Normal file
56
serveradmin.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# ssh
|
||||
ssh root@167.172.247.123
|
||||
|
||||
# certs
|
||||
certbot --nginx -d comalyr.com -d ...
|
||||
|
||||
# Code Server
|
||||
curl -fsSL https://code-server.dev/install.sh | sh
|
||||
pm2 start code-server --name code
|
||||
cat ~/.config/code-server/config.yaml
|
||||
|
||||
# pm2
|
||||
## For Running the Servers
|
||||
|
||||
## start your app
|
||||
pm2 start "npm run start" --name comalyr
|
||||
|
||||
## see running processes
|
||||
pm2 list
|
||||
|
||||
## view logs
|
||||
pm2 logs
|
||||
pm2 logs comalyr
|
||||
|
||||
## restart
|
||||
pm2 restart comalyr
|
||||
|
||||
## stop
|
||||
pm2 stop comalyr
|
||||
|
||||
## save all current processes to be run on startup
|
||||
pm2 save
|
||||
|
||||
# nginx
|
||||
|
||||
tail -f /var/log/nginx/access.log
|
||||
tail -f /var/log/nginx/error.log
|
||||
cat /var/log/nginx/access.log
|
||||
|
||||
## list config
|
||||
cat /etc/nginx/sites-available/norn
|
||||
nano /etc/nginx/sites-available/norn
|
||||
|
||||
## restart
|
||||
systemctl restart nginx
|
||||
|
||||
# Postgres
|
||||
|
||||
systemctl status postgresql
|
||||
|
||||
# debugging
|
||||
|
||||
curl http://localhost:8080
|
||||
|
||||
curl -v https://comalyr.com 2>&1 | head -30
|
||||
this will list out the process of connecting
|
||||
@@ -14,6 +14,7 @@
|
||||
--quillred: #DE3F3F;
|
||||
--brown: #812A18;
|
||||
--darkbrown: #3f0808;
|
||||
--divider: rgb(223 201 169);
|
||||
|
||||
--house-src: /_/icons/house.svg;
|
||||
--nodes-src: /_/icons/nodes.svg;
|
||||
@@ -39,9 +40,10 @@
|
||||
:root.dark {
|
||||
--main: #000000;
|
||||
--app: #180404;
|
||||
--accent: #8a7454;
|
||||
--accent: #935757;
|
||||
--accent2: var(--gold);
|
||||
--window: #340f0f;
|
||||
--divider: rgb(69 34 34);
|
||||
|
||||
--house-src: /_/icons/housedark.svg;
|
||||
--nodes-src: /_/icons/nodesdark.svg;
|
||||
|
||||
@@ -150,6 +150,7 @@ class Dashboard extends Shadow {
|
||||
.gap(8);
|
||||
});
|
||||
})
|
||||
.gap(0.5, em)
|
||||
.paddingTop(4, pct)
|
||||
.paddingLeft(5, pct)
|
||||
.width(100, pct)
|
||||
|
||||
203
ui/desktop/apps/Dashboard/alt.js
Normal file
203
ui/desktop/apps/Dashboard/alt.js
Normal file
@@ -0,0 +1,203 @@
|
||||
class Dashboard extends Shadow {
|
||||
|
||||
gridStyle() {
|
||||
return {
|
||||
table: {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'box-shadow': 'none',
|
||||
'font-size': '0.9em',
|
||||
'max-width': '90%'
|
||||
},
|
||||
th: {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'border': 'none',
|
||||
'border-bottom': '1px solid var(--divider)'
|
||||
},
|
||||
td: {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'border': 'none',
|
||||
'border-bottom': '1px solid var(--divider)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gridCSS() {
|
||||
css(`
|
||||
input.gridjs-input {
|
||||
background-color: var(--window);
|
||||
color: var(--accent);
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--divider);
|
||||
border-radius: 0;
|
||||
margin-left: 5em
|
||||
}
|
||||
|
||||
.gridjs-wrapper {
|
||||
box-shadow: none;
|
||||
padding-left: 4em;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
render() {
|
||||
VStack(() => {
|
||||
|
||||
if(window.location.pathname.startsWith("/my")) {
|
||||
h1(global.profile.name);
|
||||
return
|
||||
}
|
||||
else if(!window.location.pathname.includes("comalyr")) {
|
||||
return
|
||||
}
|
||||
|
||||
h1("Website Inquiries")
|
||||
.paddingLeft(5, pct)
|
||||
|
||||
VStack(() => {
|
||||
VStack(() => {
|
||||
p("Contact Us")
|
||||
.marginBottom(2, vh)
|
||||
.marginLeft(5, em)
|
||||
.fontStyle("italic")
|
||||
|
||||
ZStack(() => {
|
||||
new gridjs.Grid({
|
||||
columns: [
|
||||
{
|
||||
name: "Time",
|
||||
sort: {
|
||||
compare: (a, b) => {
|
||||
const parse = (str) => {
|
||||
const [datePart, timePart] = str.trim().split(/\s+/);
|
||||
const [month, day, year] = datePart.split('.');
|
||||
const normalized = timePart.replace(/(\d+):(\d+)(am|pm)/i, (_, h, m, meridiem) => {
|
||||
let hours = parseInt(h);
|
||||
if (meridiem.toLowerCase() === 'pm' && hours !== 12) hours += 12;
|
||||
if (meridiem.toLowerCase() === 'am' && hours === 12) hours = 0;
|
||||
return `${String(hours).padStart(2, '0')}:${m}:00`;
|
||||
});
|
||||
return new Date(`${year}-${month}-${day}T${normalized}`);
|
||||
}
|
||||
return parse(a) - parse(b);
|
||||
}
|
||||
}
|
||||
},
|
||||
"First", "Last", "Email", "Phone",
|
||||
{
|
||||
name: "Message",
|
||||
formatter: (cell) => gridjs.html(`
|
||||
<div class="messageCell" style="
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
max-width: 300px;
|
||||
" data-message="${cell.replace(/"/g, '"')}">
|
||||
${cell}
|
||||
</div>
|
||||
`)
|
||||
},
|
||||
"County"
|
||||
],
|
||||
data: global.currentNetwork.data.contact.map(e => [
|
||||
e.time.replace(/:\d{6}(?=am|pm)/i, '')
|
||||
.replace('-', ' ')
|
||||
.replace(/(\d{1,2}:\d{2})(am|pm)/i, (_, time, meridiem) => {
|
||||
const [h, m] = time.split(':');
|
||||
return `${h.padStart(2, '0')}:${m}${meridiem.toLowerCase()}`;
|
||||
}),
|
||||
e.fname,
|
||||
e.lname,
|
||||
e.email,
|
||||
e.phone,
|
||||
e.message,
|
||||
e.county ?? "Not Specified"
|
||||
]),
|
||||
sort: {
|
||||
multiColumn: false,
|
||||
initialState: {
|
||||
columnIndex: 0,
|
||||
direction: "desc"
|
||||
}
|
||||
},
|
||||
search: true,
|
||||
style: this.gridStyle()
|
||||
}).render(quill.rendering.last)
|
||||
|
||||
this.gridCSS()
|
||||
})
|
||||
.overflow("hidden")
|
||||
})
|
||||
.gap(0.5, em)
|
||||
|
||||
VStack(() => {
|
||||
p("Join")
|
||||
.marginBottom(2, vh)
|
||||
.marginLeft(5, em)
|
||||
.fontStyle("italic")
|
||||
|
||||
ZStack(() => {
|
||||
new gridjs.Grid({
|
||||
columns: [
|
||||
{
|
||||
name: "Time",
|
||||
sort: {
|
||||
compare: (a, b) => {
|
||||
const parse = (str) => {
|
||||
const [datePart, timePart] = str.trim().split(/\s+/);
|
||||
const [month, day, year] = datePart.split('.');
|
||||
const normalized = timePart.replace(/(\d+):(\d+)(am|pm)/i, (_, h, m, meridiem) => {
|
||||
let hours = parseInt(h);
|
||||
if (meridiem.toLowerCase() === 'pm' && hours !== 12) hours += 12;
|
||||
if (meridiem.toLowerCase() === 'am' && hours === 12) hours = 0;
|
||||
return `${String(hours).padStart(2, '0')}:${m}:00`;
|
||||
});
|
||||
return new Date(`${year}-${month}-${day}T${normalized}`);
|
||||
}
|
||||
return parse(a) - parse(b);
|
||||
}
|
||||
}
|
||||
},
|
||||
"First", "Last", "Email", "Phone", "County"
|
||||
],
|
||||
data: global.currentNetwork.data.join.map(e => [
|
||||
e.time.replace(/:\d{6}(?=am|pm)/i, '')
|
||||
.replace('-', ' ')
|
||||
.replace(/(\d{1,2}:\d{2})(am|pm)/i, (_, time, meridiem) => {
|
||||
const [h, m] = time.split(':');
|
||||
return `${h.padStart(2, '0')}:${m}${meridiem.toLowerCase()}`;
|
||||
}),
|
||||
e.fname,
|
||||
e.lname,
|
||||
e.email,
|
||||
e.phone,
|
||||
e.county ?? "Not Specified"
|
||||
]),
|
||||
sort: true,
|
||||
search: true,
|
||||
style: this.gridStyle()
|
||||
}).render(quill.rendering.last)
|
||||
|
||||
this.gridCSS()
|
||||
})
|
||||
.marginBottom(3, em)
|
||||
.overflow("hidden")
|
||||
})
|
||||
.gap(0.5, em)
|
||||
})
|
||||
.gap(4, em)
|
||||
})
|
||||
.gap(0.5, em)
|
||||
.paddingTop(4, pct)
|
||||
.width(100, pct)
|
||||
.height(100, pct);
|
||||
}
|
||||
}
|
||||
|
||||
register(Dashboard)
|
||||
@@ -4,13 +4,13 @@ class People extends Shadow {
|
||||
h1("Members")
|
||||
.fontWeight("bold")
|
||||
.marginBottom(2, em)
|
||||
.marginLeft(4, em)
|
||||
.marginLeft(2, em)
|
||||
|
||||
VStack(() => {
|
||||
VStack(() => {
|
||||
p("Officers")
|
||||
.marginBottom(2, vh)
|
||||
.marginLeft(8, em)
|
||||
.marginLeft(4, em)
|
||||
.fontStyle("italic")
|
||||
|
||||
ZStack(() => {
|
||||
@@ -27,35 +27,36 @@ class People extends Shadow {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'box-shadow': 'none',
|
||||
'font-size': '0.9em'
|
||||
'font-size': '0.9em',
|
||||
'max-width': '90%'
|
||||
},
|
||||
th: {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'border': 'none',
|
||||
'border-bottom': '1px solid rgb(69 53 53)'
|
||||
},
|
||||
td: {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'border': 'none',
|
||||
'border-bottom': '1px solid rgb(69 53 53)'
|
||||
'border-bottom': '1px solid var(--divider)'
|
||||
}
|
||||
}
|
||||
}).render(quill.rendering.last)
|
||||
})
|
||||
.overflow("hidden")
|
||||
})
|
||||
.gap(0.5, em)
|
||||
|
||||
VStack(() => {
|
||||
p("Stripe Subscribers")
|
||||
.marginBottom(2, vh)
|
||||
.marginLeft(8, em)
|
||||
.marginLeft(4, em)
|
||||
.fontStyle("italic")
|
||||
|
||||
ZStack(() => {
|
||||
new gridjs.Grid({
|
||||
columns: ["Amount", "Name", "Email", "Phone", "Area", "Created"],
|
||||
columns: ["Amount", "Name", "Email", "Phone", "County", "Created"],
|
||||
data: global.currentNetwork.data.stripeMembers.map(m => [
|
||||
"$" + m.subscriptions[0].amount,
|
||||
m.name,
|
||||
@@ -81,19 +82,19 @@ class People extends Shadow {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'box-shadow': 'none',
|
||||
'font-size': '0.9em'
|
||||
'font-size': '0.9em',
|
||||
'max-width': '90%'
|
||||
},
|
||||
th: {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'border': 'none',
|
||||
'border-bottom': '1px solid rgb(69 53 53)'
|
||||
},
|
||||
td: {
|
||||
'background-color': 'var(--window)',
|
||||
'color': 'var(--accent)',
|
||||
'border': 'none',
|
||||
'border-bottom': '1px solid rgb(69 53 53)'
|
||||
'border-bottom': '1px solid var(--divider)'
|
||||
}
|
||||
}
|
||||
}).render(quill.rendering.last)
|
||||
@@ -103,17 +104,18 @@ class People extends Shadow {
|
||||
background-color: var(--window);
|
||||
color: var(--accent);
|
||||
border: none;
|
||||
border-bottom: 1px solid rgb(69 53 53);
|
||||
border-bottom: 1px solid var(--divider);
|
||||
border-radius: 0;
|
||||
margin-left: 8em
|
||||
margin-left: 4em
|
||||
}
|
||||
|
||||
.gridjs-wrapper {
|
||||
box-shadow: none;
|
||||
padding-left: 8em;
|
||||
padding-left: 3em;
|
||||
}
|
||||
`)
|
||||
})
|
||||
.marginBottom(3, em)
|
||||
})
|
||||
.gap(0.5, em)
|
||||
})
|
||||
|
||||
@@ -33,6 +33,16 @@ class AppWindow extends Shadow {
|
||||
case "Settings":
|
||||
Settings()
|
||||
break;
|
||||
default:
|
||||
this.innerHTML = `
|
||||
<iframe
|
||||
src="/apps/parchment"
|
||||
sandbox="allow-scripts allow-same-origin allow-forms"
|
||||
width="100%"
|
||||
height="100%"
|
||||
>
|
||||
</iframe>
|
||||
`
|
||||
}
|
||||
})
|
||||
.overflow("scroll")
|
||||
|
||||
Reference in New Issue
Block a user