diff --git a/main.go b/main.go
index ec11478..4228e84 100644
--- a/main.go
+++ b/main.go
@@ -41,6 +41,20 @@ func main() {
Automigrate: isGoRun,
})
+ app.OnAfterBootstrap().Add(func(e *core.BootstrapEvent) error {
+ // update app settings on first run
+ settings := app.Settings()
+ if app.Settings().Meta.AppName == "Acme" {
+ app.Settings().Meta.AppName = "Qoma"
+ app.Settings().Meta.HideControls = true
+ err := app.Dao().SaveSettings(settings)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+
// serve site
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
switch isGoRun {
@@ -95,11 +109,12 @@ func main() {
return nil
})
+ // ssh key setup
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
// create ssh key if it doesn't exist
getSSHKey()
// api route to return public key
- e.Router.GET("/getkey", func(c echo.Context) error {
+ e.Router.GET("/api/qoma/getkey", func(c echo.Context) error {
requestData := apis.RequestInfo(c)
if requestData.Admin == nil {
return apis.NewForbiddenError("Forbidden", nil)
@@ -113,6 +128,19 @@ func main() {
return nil
})
+ // other api routes
+ app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
+ // check if first time setup on login page
+ e.Router.GET("/api/qoma/first-run", func(c echo.Context) error {
+ adminNum, err := app.Dao().TotalAdmins()
+ if err != nil {
+ return err
+ }
+ return c.JSON(http.StatusOK, map[string]bool{"firstRun": adminNum == 0})
+ })
+ return nil
+ })
+
// start ticker for server updates
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
go serverUpdateTicker()
diff --git a/migrations/1720568457_collections_snapshot.go b/migrations/1720568457_collections_snapshot.go
index fdb2198..993c8ec 100644
--- a/migrations/1720568457_collections_snapshot.go
+++ b/migrations/1720568457_collections_snapshot.go
@@ -78,7 +78,7 @@ func init() {
{
"id": "2hz5ncl8tizk5nx",
"created": "2024-07-07 16:08:20.979Z",
- "updated": "2024-07-13 01:18:43.529Z",
+ "updated": "2024-07-13 23:20:50.678Z",
"name": "systems",
"type": "base",
"system": false,
@@ -155,9 +155,7 @@ func init() {
}
}
],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_eggNgAn` + "`" + ` ON ` + "`" + `systems` + "`" + ` (` + "`" + `name` + "`" + `)"
- ],
+ "indexes": [],
"listRule": null,
"viewRule": null,
"createRule": null,
diff --git a/site/src/components/add-server.tsx b/site/src/components/add-server.tsx
index 0d15b06..51d38d4 100644
--- a/site/src/components/add-server.tsx
+++ b/site/src/components/add-server.tsx
@@ -43,7 +43,7 @@ export function AddServerButton() {
return
}
// get public key
- pb.send('/getkey', {}).then(({ key }) => {
+ pb.send('/api/qoma/getkey', {}).then(({ key }) => {
$publicKey.set(key)
})
}, [open])
diff --git a/site/src/components/command-palette.tsx b/site/src/components/command-palette.tsx
index c1b6254..fedaecb 100644
--- a/site/src/components/command-palette.tsx
+++ b/site/src/components/command-palette.tsx
@@ -1,6 +1,13 @@
'use client'
-import { Database, Github, Home, Server } from 'lucide-react'
+import {
+ Database,
+ DatabaseBackupIcon,
+ Github,
+ LayoutDashboard,
+ MailIcon,
+ Server,
+} from 'lucide-react'
import {
CommandDialog,
@@ -16,7 +23,7 @@ import { useEffect, useState } from 'react'
import { useStore } from '@nanostores/react'
import { $servers, navigate } from '@/lib/stores'
-export default function () {
+export default function CommandPalette() {
const [open, setOpen] = useState(false)
const servers = useStore($servers)
@@ -39,24 +46,16 @@ export default function () {
No results found.
{
navigate('/')
setOpen((open) => !open)
}}
>
-
- Home
+
+ Dashboard
Page
- {
- window.location.href = '/_/#/collections?collectionId=2hz5ncl8tizk5nx'
- }}
- >
-
- Admin UI
- PocketBase
-
{
window.location.href = 'https://github.com/henrygd'
@@ -79,9 +78,42 @@ export default function () {
>
{server.name}
+ {server.host}
))}
+
+
+ {
+ window.location.href = '/_/#/collections?collectionId=2hz5ncl8tizk5nx'
+ }}
+ >
+
+ PocketBase
+ Admin
+
+ {
+ window.location.href = '/_/#/settings/backups'
+ }}
+ >
+
+ Database backups
+ Admin
+
+ {
+ window.location.href = '/_/#/settings/mail'
+ }}
+ >
+
+ SMTP settings
+ Admin
+
+
)
diff --git a/site/src/components/login.tsx b/site/src/components/login.tsx
index 62af7ff..d1d8e5e 100644
--- a/site/src/components/login.tsx
+++ b/site/src/components/login.tsx
@@ -1,11 +1,19 @@
import { UserAuthForm } from '@/components/user-auth-form'
import { Logo } from './logo'
-import { useEffect } from 'react'
+import { useEffect, useState } from 'react'
+import { pb } from '@/lib/stores'
export default function () {
+ const [isFirstRun, setFirstRun] = useState(false)
+
useEffect(() => {
document.title = 'Login / Qoma'
+
+ pb.send('/api/qoma/first-run', {}).then(({ firstRun }) => {
+ setFirstRun(firstRun)
+ })
}, [])
+
return (
@@ -15,9 +23,11 @@ export default function () {
Qoma
-
Please sign in to your account
+
+ {isFirstRun ? 'Please create your admin account' : 'Please sign in to your account'}
+
-
+
{/* todo: add forgot password section to readme and link to section
reset w/ command or link to pb reset */}
diff --git a/site/src/components/routes/home.tsx b/site/src/components/routes/home.tsx
index ea7524c..d6eb676 100644
--- a/site/src/components/routes/home.tsx
+++ b/site/src/components/routes/home.tsx
@@ -2,7 +2,7 @@ import { Suspense, lazy, useEffect } from 'react'
// import { DataTable } from '../server-table/data-table'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card'
-const DataTable = lazy(() => import('../server-table/data-table'))
+const SystemsTable = lazy(() => import('../server-table/systems-table'))
export default function () {
useEffect(() => {
@@ -24,7 +24,7 @@ export default function () {
-
+
diff --git a/site/src/components/server-table/data-table.tsx b/site/src/components/server-table/systems-table.tsx
similarity index 99%
rename from site/src/components/server-table/data-table.tsx
rename to site/src/components/server-table/systems-table.tsx
index 909af02..33dea94 100644
--- a/site/src/components/server-table/data-table.tsx
+++ b/site/src/components/server-table/systems-table.tsx
@@ -103,7 +103,7 @@ function sortableHeader(column: Column, name: string, Ico
)
}
-export default function () {
+export default function SystemsTable() {
const data = useStore($servers)
// const [deleteServer, setDeleteServer] = useState({} as SystemRecord)
const [sorting, setSorting] = useState([])
@@ -135,7 +135,7 @@ export default function () {
onClick={() => copyToClipboard(info.getValue() as string)}
>
{info.getValue() as string}
-
+
)
diff --git a/site/src/components/ui/command.tsx b/site/src/components/ui/command.tsx
index 97db253..1cd97be 100644
--- a/site/src/components/ui/command.tsx
+++ b/site/src/components/ui/command.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { type DialogProps } from '@radix-ui/react-dialog'
+import { DialogTitle, type DialogProps } from '@radix-ui/react-dialog'
import { Command as CommandPrimitive } from 'cmdk'
import { Search } from 'lucide-react'
@@ -27,6 +27,9 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
return (