feat/routes (#9)

* refactor: decouple core logic from global configuration

* fix: apply consistent error handling across application

* refactor: improve component rendering for better performance

* feat: migrate views to use  directory for components

* feat: streamline UI imports and package structure

* feat: update templ version to v0.3.865

* feat: enhance application observability with status check

* refactor: decouple database setup from command line tools

* refactor: replace card component with styled divs for improved customization

* refactor: rename and move Helia console components to blocks

* chore: reorganize controllers under handlers

* feat: implement home page UI with registration form

* <no value>

* fix: correct file path in templ error messages

* refactor: use web component for connection status indicator

* feat: enhance connection status indicator with visual cue

* chore: move Helia initialization script to helia package

* refactor: rename 'appComponent' to 'consoleComponent'

* chore: standardize import paths across vault package

* feat: introduce common error definitions for API responses

* refactor: centralize handle input logic into reusable component

* style: adjust user handle input for better visual feedback

* build: update templ generated files

* feat: automate builds, archives, and releases

* ci: consolidate publishing workflows for improved automation

* ci: simplify deployment workflows and leverage Cloudflare

* ci: allow manual deployment initiation

* ci: add  trigger for deploy workflow

* docs: Update README with new development workflow and component details
This commit is contained in:
2025-05-21 12:38:54 -04:00
committed by GitHub
parent 8540fb5dd1
commit 78edae2785
116 changed files with 828 additions and 852 deletions

View File

@@ -1,67 +0,0 @@
# This workflow will create a GitHub release every time a tag is pushed
name: Deploy @onsonr/es to npm
on:
push:
branches:
- "master"
- "main"
jobs:
release:
permissions:
contents: write
runs-on: ubuntu-latest
if: contains(github.event.head_commit.modified, 'src/')
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v3
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install deps (with cache)
run: pnpm install
- name: Setup Git Config
run: |
git config user.name "Prad N."
git config user.email "prad@sonr.io"
- name: Build
run: pnpm run build
- name: "Automated Version Bump and Release"
run: |
git add .
git commit -m "chore: update build artifacts [skip ci]" || echo "No changes to commit"
pnpm version patch
git push
git push --tags
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}

View File

@@ -1,138 +0,0 @@
name: Check PR
on:
pull_request:
merge_group:
permissions:
contents: read # for TimonVS/pr-labeler-action to read config file
pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR
jobs:
verify-pr:
name: Test Lints
if: github.event_name == 'pull_request'
permissions:
contents: read # for TimonVS/pr-labeler-action to read config file
pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required to fetch all history for merging
- uses: TimonVS/pr-labeler-action@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/pr-labeler.yml # optional, .github/pr-labeler.yml is the default value
- name: Trunk Check
uses: trunk-io/trunk-action@v1
test-builds:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
name: Test Builds
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: onsonr/sonr
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- name: Run Sonrd Build
run: make build
test-unit:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
name: Test Unit
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: onsonr/sonr
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- run: make test-unit
test-race:
runs-on: ubuntu-latest
if: github.event_name == 'merge_group'
name: Test Race
continue-on-error: true
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: onsonr/sonr
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- run: make test-race
test-cover:
runs-on: ubuntu-latest
if: github.event_name == 'merge_group'
name: Test Coverage
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: onsonr/sonr
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- run: make test-cover
validate-release:
if: github.event_name == 'merge_group' || github.event_name == 'pull_request'
runs-on: ubuntu-latest
name: Test Release
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: onsonr/sonr
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- name: Commitizen Dry Run
uses: commitizen-tools/commitizen-action@master
with:
push: false
dry_run: true
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: main
- name: Check GoReleaser Config
run: make release-check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: GoReleaser Dry Run
run: make release-dry
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

30
.github/workflows/deploy.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Deploy Worker
on:
push:
workflow_dispatch:
workflow_call:
jobs:
wrangler:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: current
- name: Deploy
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
workingDirectory: cmd/vault

View File

@@ -1,66 +0,0 @@
name: New Release
on:
release:
types: [published]
permissions:
contents: write
issues: write
jobs:
buf_push:
name: Publish Protobufs
runs-on: ubuntu-latest
steps:
# Run `git checkout`
- uses: actions/checkout@v4
# Install the `buf` CLI
- uses: bufbuild/buf-setup-action@v1
# Push only the Input in `proto` to the BSR
- uses: bufbuild/buf-push-action@v1
continue-on-error: true
with:
input: proto
buf_token: ${{ secrets.BUF_TOKEN }}
container-push:
name: Publish Docker Images
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/onsonr/sonr:latest
docs-push:
runs-on: ubuntu-latest
name: Publish Tech Docs
steps:
- uses: actions/checkout@v4
- name: Configure Git Credentials
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
- uses: actions/setup-python@v5
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v4
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force

View File

@@ -1,51 +0,0 @@
name: New Tag
on:
pull_request:
types: [closed]
push:
tags:
- v*
branches:
- main
permissions:
contents: write
jobs:
new-release:
name: Create Release
if: startsWith(github.ref, 'refs/tags/')
permissions: write-all
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: onsonr/sonr
fetch-depth: 0
fetch-tags: true
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Run GoReleaser
run: make release
env:
GITHUB_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
GITHUB_PERSONAL_AUTH_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
REDDIT_APP_ID: ${{ secrets.REDDIT_APP_ID }}
REDDIT_SECRET: ${{ secrets.REDDIT_SECRET }}
REDDIT_USERNAME: ${{ secrets.REDDIT_USERNAME }}
REDDIT_PASSWORD: ${{ secrets.REDDIT_PASSWORD }}

View File

@@ -1,33 +0,0 @@
name: Post Merge
on:
pull_request:
types: [closed]
permissions:
contents: write
issues: write
jobs:
bump-version:
name: Version Bump
if: |
github.event.pull_request.merged == true &&
github.event.pull_request.user.login != 'dependabot[bot]' &&
github.event.pull_request.user.login != 'dependabot-preview[bot]'
runs-on: ubuntu-latest
steps:
- name: Check out
uses: actions/checkout@v4
with:
fetch-depth: 0
ssh-key: "${{ secrets.COMMIT_KEY }}"
- name: Create bump and changelog
uses: commitizen-tools/commitizen-action@master
with:
push: false
increment: patch
- name: Push using ssh
run: |
git push origin main --tags

31
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: New Release
on:
push:
tags:
- "v*.*.*"
- "*"
permissions:
contents: write
issues: write
packages: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
version: "~> v2"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}

43
.goreleaser.yaml Normal file
View File

@@ -0,0 +1,43 @@
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
before:
hooks:
- go mod tidy
- sqlc generate
- templ generate
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
archives:
- formats: [tar.gz]
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
format_overrides:
- goos: windows
formats: [zip]
changelog:
sort: desc
filters:
exclude:
- "^docs:"
- "^test:"
release:
footer: >-
---
Released by [GoReleaser](https://github.com/goreleaser/goreleaser).

118
README.md
View File

@@ -33,64 +33,56 @@ docker-compose up -d
## Usage
### Run Using Docker
### Development Setup
The simplest way to run the full Motr system is with Docker Compose:
Motr uses [Task](https://taskfile.dev) for managing development workflows. Here are the primary commands:
```bash
# Start all services
docker-compose up -d
# Clean build artifacts
task clean
# View logs
docker-compose logs -f
# Build all components
task build
# Stop services
docker-compose down
# Deploy all components to Cloudflare
task deploy
# Start the local development server
task serve
```
### Run as a Local Server
### Component-specific commands
```go
package main
```bash
# Start the Vault component (Cloudflare Worker)
task start:vault
import (
"database/sql"
"log"
# Start the Frontend component
task start:front
"github.com/sonr-io/motr/app"
"github.com/sonr-io/motr/pkg/models"
"github.com/sonr-io/motr/pkg/types"
)
# Build specific components
task build:vault
task build:front
func main() {
dbq, err := setupDatabase()
if err != nil {
log.Fatal(err)
}
# Deploy specific components to Cloudflare
task deploy:vault
task deploy:front
```
config := &types.Config{
MotrToken: "your-token",
SonrChainID: "sonr-testnet-1",
// Other configuration options
}
### Database operations
vault, err := app.New(config, dbq)
if err != nil {
log.Fatal(err)
}
```bash
# Generate SQL models using sqlc
task gen:sqlc
// Start the server
vault.Start(":8080")
}
func setupDatabase() (*models.Queries, error) {
// Initialize your database connection
// ...
}
# Migrate the database
task db:migrate
```
### Compile to WebAssembly
The project uses WebAssembly for cross-platform compatibility. Components are compiled automatically when using the Task commands above, but you can also build manually:
```sh
# Build the signer as WASM
GOOS=js GOARCH=wasm go build -o build/signer.wasm ./cmd/signer/main.go
@@ -115,6 +107,7 @@ Motr can be integrated into progressive web applications, providing:
Motr consists of several components:
- **Vault**: Core component deployed as a Cloudflare Worker with WebAssembly
- **Controller**: Manages WebAuthn credential creation and verification
- **Resolver**: Handles name resolution and identity lookups
- **Signer**: WebAssembly-based cryptographic operations for secure signing
@@ -124,27 +117,62 @@ Motr consists of several components:
### Component Details
1. **Controller**
1. **Vault**
- Core component deployed as a Cloudflare Worker
- Manages decentralized identity and authentication
- Integrates with IPFS/Helia for decentralized storage
- Uses WebAssembly plugins for cryptographic operations
- Package located at `cmd/vault/`
2. **Controller**
- Manages user credentials and authentication
- Integrates with WebAuthn for credential storage
- Containerized for easy deployment
2. **Resolver**
- Uses SQLite via D1 database for persistent storage
3. **Resolver**
- Resolves Sonr names to addresses and profiles
- Serves as a gateway to the Sonr network
- Implemented as a Cloudflare Worker
3. **Signer**
4. **Signer**
- Secure cryptographic operations
- WebAssembly-based for cross-platform compatibility
- Handles key management and signatures
## Development
### Build System
Motr uses the following build tools:
- **Task**: Task runner for development workflows
- **GoReleaser**: Handles building and releasing Go applications
- **SQLC**: Generates type-safe Go code from SQL
- **Templ**: Template engine for Go HTML templates
- **Air**: Live reload for Go applications during development
- **Bun**: JavaScript runtime and package manager
### Release Process
```bash
# Create a new release
task release
```
The release process uses GoReleaser with configuration in `.goreleaser.yaml`.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
To contribute:
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes using conventional commits (`git commit -m 'feat: add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
[MIT](LICENSE)

View File

@@ -13,6 +13,10 @@ tasks:
- task: tidy:front
- task: tidy:root
serve:
desc: Serve the app with air
cmd: air
deploy:
desc: Deploy all
cmds:

View File

@@ -4,9 +4,9 @@
package main
import (
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/routes"
"github.com/sonr-io/motr/sink/config"
)
func main() {

View File

@@ -4,9 +4,9 @@
package main
import (
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/routes"
"github.com/sonr-io/motr/sink/config"
)
func main() {

View File

@@ -1,33 +0,0 @@
package inputs
templ HandleInitial() {
<div hx-target="this" hx-swap="outerHTML">
<sl-input name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required hx-post="/register/profile" hx-indicator="#handle-indicator" autofocus>
<div slot="prefix">
<sl-icon name="at-sign" library="sonr"></sl-icon>
</div>
</sl-input>
</div>
<br/>
}
templ HandleError(value string, helpText string) {
<sl-input name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required class="border-red-500" value={ value } help-text={ helpText }>
<div slot="prefix">
<sl-icon name="at-sign" library="sonr"></sl-icon>
</div>
<div slot="suffix" style="color: #B54549;">
<sl-icon name="x"></sl-icon>
</div>
</sl-input>
<br/>
}
templ HandleSuccess(value string) {
<sl-input name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required class="border-green-500" value={ value } disabled>
<div slot="prefix" style="color: #46A758;">
<sl-icon name="at-sign" library="sonr"></sl-icon>
</div>
</sl-input>
<br/>
}

View File

@@ -1,91 +0,0 @@
package views
import (
"github.com/sonr-io/motr/ui"
"github.com/sonr-io/motr/components/dashboard"
"time"
)
var heliaCardScriptHandle = templ.NewOnceHandle()
func DemoView(d time.Time) templ.Component {
return demoComponent(d)
}
templ demoComponent(d time.Time) {
@ui.HTML() {
@ui.Head() {
}
<sl-tab-group>
@ui.Nav() {
@ui.NavLeft() {
@ui.NavLogo("Motr")
}
@ui.NavRight() {
<sl-tab slot="nav" panel="tab-1">Time</sl-tab>
}
}
@ui.Body() {
<sl-tab-panel name="tab-1" active>
@ui.Container() {
<div class="space-y-6">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
@dashboard.HeliaStatusCard()
@dashboard.HeliaNodeIDCard()
@dashboard.HeliaDiscoveredPeersCard()
@dashboard.HeliaConnectedPeersCard()
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
@dashboard.HeliaConnectedPeersList()
@dashboard.HeliaRunningLog()
</div>
@heliaCardScriptHandle.Once() {
<script>
document.addEventListener('DOMContentLoaded', async () => {
try {
// Use the globally available instantiateHeliaNode function
const helia = window.helia = await window.instantiateHeliaNode()
window.heliaFs = await HeliaUnixfs.unixfs(helia)
helia.libp2p.addEventListener('peer:discovery', (evt) => {
window.discoveredPeers.set(evt.detail.id.toString(), evt.detail)
addToLog(`Discovered peer ${evt.detail.id.toString()}`)
})
helia.libp2p.addEventListener('peer:connect', (evt) => {
addToLog(`Connected to ${evt.detail.toString()}`)
})
helia.libp2p.addEventListener('peer:disconnect', (evt) => {
addToLog(`Disconnected from ${evt.detail.toString()}`)
})
setInterval(() => {
const statusValueEl = document.getElementById('statusValue')
if (statusValueEl) {
statusValueEl.innerHTML = helia.libp2p.status === 'started' ? 'Online' : 'Offline'
}
updateConnectedPeers()
updateDiscoveredPeers()
}, 500)
const id = await helia.libp2p.peerId.toString()
const nodeIdEl = document.getElementById('nodeId')
if (nodeIdEl) {
nodeIdEl.innerHTML = id
}
addToLog('Helia node initialized successfully')
} catch (err) {
addToLog(`Error initializing Helia: ${err.message}`)
console.error('Error initializing Helia:', err)
}
})
</script>
}
</div>
}
</sl-tab-panel>
}
</sl-tab-group>
}
}

View File

@@ -1,48 +0,0 @@
package views
import (
"github.com/sonr-io/motr/sink"
"github.com/sonr-io/motr/ui"
)
var meta = sink.DefaultMetadata()
func HomeView() templ.Component {
return homeComponent()
}
templ homeComponent() {
@ui.HTML() {
@ui.Head() {
@ui.MetaComponent(meta)
}
<sl-tab-group>
@ui.Nav() {
@ui.NavLeft() {
@ui.NavLogo("Motr")
}
@ui.NavRight() {
}
}
@ui.Body() {
@ui.Container() {
<sl-card>
<div slot="header">
<h3 class="card-title">Welcome to Motr</h3>
</div>
<div class="card-body">
<p>This is a demo of the Motr web app.</p>
<p>You can use this app to manage your Motr account.</p>
</div>
<div class="card-footer">
<sl-button type="primary" size="large" href="/register">
<sl-icon slot="prefix" library="sonr" name="passkey"></sl-icon>
Register
</sl-button>
</div>
</sl-card>
}
}
</sl-tab-group>
}
}

View File

@@ -1,25 +0,0 @@
package views
import (
"github.com/sonr-io/motr/ui"
)
templ LoginView() {
@ui.HTML() {
@ui.Head() {
@ui.MetaComponent(meta)
}
<sl-tab-group>
@ui.Nav() {
@ui.NavLeft() {
@ui.NavLogo("Motr")
}
@ui.NavRight() {
}
}
@ui.Body() {
}
</sl-tab-group>
}
}

View File

@@ -1,28 +0,0 @@
package views
import (
"github.com/sonr-io/motr/ui"
"github.com/sonr-io/motr/components/inputs"
)
templ RegisterView() {
@ui.HTML() {
@ui.Head() {
@ui.MetaComponent(meta)
}
<sl-tab-group>
@ui.Nav() {
@ui.NavLeft() {
@ui.NavLogo("Motr")
}
@ui.NavRight() {
}
}
@ui.Body() {
@ui.Container() {
@inputs.HandleInitial()
}
}
</sl-tab-group>
}
}

View File

@@ -38,7 +38,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(handle)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/account/card.templ`, Line: 11, Col: 43}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/account/card.templ`, Line: 11, Col: 43}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -51,7 +51,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(addr)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/account/card.templ`, Line: 18, Col: 42}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/account/card.templ`, Line: 18, Col: 42}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
@@ -64,7 +64,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(block)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/account/card.templ`, Line: 23, Col: 47}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/account/card.templ`, Line: 23, Col: 47}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
@@ -77,7 +77,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/account/card.templ`, Line: 27, Col: 32}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/account/card.templ`, Line: 27, Col: 32}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
@@ -120,7 +120,7 @@ func optionComponent(account models.Account) templ.Component {
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(account.Address)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/account/card.templ`, Line: 37, Col: 19}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/account/card.templ`, Line: 37, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -163,7 +163,7 @@ func rowComponent(account models.Account) templ.Component {
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(account.Address)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/account/card.templ`, Line: 45, Col: 19}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/account/card.templ`, Line: 45, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {

View File

@@ -38,7 +38,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(handle)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/activity/card.templ`, Line: 11, Col: 43}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/activity/card.templ`, Line: 11, Col: 43}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -51,7 +51,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(addr)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/activity/card.templ`, Line: 18, Col: 42}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/activity/card.templ`, Line: 18, Col: 42}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
@@ -64,7 +64,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(block)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/activity/card.templ`, Line: 23, Col: 47}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/activity/card.templ`, Line: 23, Col: 47}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
@@ -77,7 +77,7 @@ func cardComponent(handle, addr, block, name string) templ.Component {
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/activity/card.templ`, Line: 27, Col: 32}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/activity/card.templ`, Line: 27, Col: 32}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
@@ -120,7 +120,7 @@ func optionComponent(account models.Activity) templ.Component {
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(account.Status)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/activity/card.templ`, Line: 37, Col: 18}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/activity/card.templ`, Line: 37, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -163,7 +163,7 @@ func rowComponent(account models.Activity) templ.Component {
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(account.Status)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `middleware/controllers/activity/card.templ`, Line: 45, Col: 18}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `controllers/activity/card.templ`, Line: 45, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {

View File

@@ -1,6 +1,6 @@
package vault
import "github.com/sonr-io/motr/middleware/controllers/credential"
import "github.com/sonr-io/motr/controllers/credential"
type LoginOptions struct {
Account string

View File

@@ -2,10 +2,10 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleDefaultExpired(c echo.Context) error {
func HandleDefaultError(c echo.Context) error {
return middleware.Render(c, views.HomeView())
}

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleDefaultIndex(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleDefaultValid(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleLoginCheck(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleLoginFinish(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleLoginInitial(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleLoginStart(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleRegisterCheck(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleRegisterFinish(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleRegisterInitial(c echo.Context) error {

View File

@@ -2,8 +2,8 @@ package handlers
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/components/views"
"github.com/sonr-io/motr/middleware"
"github.com/sonr-io/motr/ui/views"
)
func HandleRegisterStart(c echo.Context) error {

38
handlers/status_check.go Normal file
View File

@@ -0,0 +1,38 @@
package handlers
import (
"github.com/labstack/echo/v4"
)
// StatusCheck is a struct that represents the status of the application
type StatusCheck struct {
Ok bool `json:"ok"`
Services []struct {
Name string `json:"name"`
Ok bool `json:"ok"`
} `json:"services"`
}
// HandleStatusCheck is a handler that checks the status of the application
func HandleStatusCheck(c echo.Context) error {
return c.JSON(200, StatusCheck{
Ok: true,
Services: []struct {
Name string `json:"name"`
Ok bool `json:"ok"`
}{
{
Name: "IPFS",
Ok: true,
},
{
Name: "IBC",
Ok: true,
},
{
Name: "Sonr",
Ok: true,
},
},
})
}

View File

@@ -10,7 +10,7 @@ import (
"strconv"
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/sink/config"
"github.com/syumai/workers/cloudflare"
"github.com/syumai/workers/cloudflare/cache"
)

View File

@@ -8,8 +8,8 @@ import (
"github.com/labstack/echo/v4"
"github.com/segmentio/ksuid"
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/sink"
"github.com/sonr-io/motr/sink/config"
"github.com/sonr-io/motr/sink/models"
"github.com/syumai/workers/cloudflare/kv"
)

View File

@@ -5,7 +5,7 @@ package middleware
import (
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/sink/config"
)
// UseSession is a middleware that adds a new key to the context

View File

@@ -4,14 +4,14 @@
package routes
import (
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/handlers"
"github.com/sonr-io/motr/sink/config"
)
func SetupRoutes(c *config.Server) {
// Home
c.GET("/", handlers.HandleDefaultIndex)
c.GET("/expired", handlers.HandleDefaultExpired)
c.GET("/expired", handlers.HandleDefaultError)
c.GET("/valid", handlers.HandleDefaultValid)
// Login
@@ -25,4 +25,7 @@ func SetupRoutes(c *config.Server) {
c.GET("/register/:handle", handlers.HandleRegisterStart)
c.POST("/register/:handle/check", handlers.HandleRegisterCheck)
c.POST("/register/:handle/finish", handlers.HandleRegisterFinish)
// Status
c.GET("/status", handlers.HandleStatusCheck)
}

10
sink/base/errors.go Normal file
View File

@@ -0,0 +1,10 @@
package base
import (
"errors"
)
var (
ErrInvalidRequest = errors.New("invalid request")
ErrNotFound = errors.New("not found")
)

View File

@@ -1,11 +1,11 @@
version: "2"
sql:
- engine: "sqlite"
queries: "./cmd/vault/query.sql"
schema: "./cmd/vault/schema.sql"
queries: "./sink/migrations/query.sql"
schema: "./sink/migrations/schema.sql"
gen:
go:
emit_interface: true
emit_json_tags: true
package: "models"
out: "./internal/sink/models"
out: "./sink/models"

View File

@@ -1,7 +1,7 @@
package dashboard
package helia
// StatusCard component for displaying Helia node status
templ HeliaStatusCard() {
templ StatusCard() {
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
<h2 class="text-4xl font-semibold text-gray-800 dark:text-neutral-200">
@@ -18,7 +18,7 @@ templ HeliaStatusCard() {
}
// NodeIDCard component for displaying Helia node ID
templ HeliaNodeIDCard() {
templ NodeIDCard() {
<div>
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
@@ -36,7 +36,7 @@ templ HeliaNodeIDCard() {
}
// DiscoveredPeersCard component for displaying discovered peers count
templ HeliaDiscoveredPeersCard() {
templ DiscoveredPeersCard() {
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
<h2 class="text-4xl font-semibold text-gray-800 dark:text-neutral-200">
@@ -52,7 +52,7 @@ templ HeliaDiscoveredPeersCard() {
}
// ConnectedPeersCard component for displaying connected peers count
templ HeliaConnectedPeersCard() {
templ ConnectedPeersCard() {
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
<h2 class="text-4xl font-semibold text-gray-800 dark:text-neutral-200">
@@ -67,7 +67,7 @@ templ HeliaConnectedPeersCard() {
}
// Optional: Create a component for a connected peers list if needed
templ HeliaConnectedPeersList() {
templ ConnectedPeersList() {
<div class="p-4 bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<h3 class="text-lg font-medium text-gray-800 dark:text-neutral-200 mb-2">Connected Peers List</h3>
<ul id="connectedPeersList" class="text-sm text-gray-600 dark:text-neutral-400"></ul>
@@ -75,7 +75,7 @@ templ HeliaConnectedPeersList() {
}
// Optional: Create a component for the running log
templ HeliaRunningLog() {
templ RunningLog() {
<div class="p-4 bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<h3 class="text-lg font-medium text-gray-800 dark:text-neutral-200 mb-2">Running Log</h3>
<div id="runningLog" class="text-sm text-gray-600 dark:text-neutral-400 h-40 overflow-y-auto font-mono"></div>

View File

@@ -1,7 +1,7 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package dashboard
package helia
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@@ -9,7 +9,7 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
// StatusCard component for displaying Helia node status
func HeliaStatusCard() templ.Component {
func StatusCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -39,7 +39,7 @@ func HeliaStatusCard() templ.Component {
}
// NodeIDCard component for displaying Helia node ID
func HeliaNodeIDCard() templ.Component {
func NodeIDCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -69,7 +69,7 @@ func HeliaNodeIDCard() templ.Component {
}
// DiscoveredPeersCard component for displaying discovered peers count
func HeliaDiscoveredPeersCard() templ.Component {
func DiscoveredPeersCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -99,7 +99,7 @@ func HeliaDiscoveredPeersCard() templ.Component {
}
// ConnectedPeersCard component for displaying connected peers count
func HeliaConnectedPeersCard() templ.Component {
func ConnectedPeersCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -129,7 +129,7 @@ func HeliaConnectedPeersCard() templ.Component {
}
// Optional: Create a component for a connected peers list if needed
func HeliaConnectedPeersList() templ.Component {
func ConnectedPeersList() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -159,7 +159,7 @@ func HeliaConnectedPeersList() templ.Component {
}
// Optional: Create a component for the running log
func HeliaRunningLog() templ.Component {
func RunningLog() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {

49
ui/app/helia/script.templ Normal file
View File

@@ -0,0 +1,49 @@
package helia
var heliaCardScriptHandle = templ.NewOnceHandle()
templ ScriptTag() {
@heliaCardScriptHandle.Once() {
<script>
document.addEventListener('DOMContentLoaded', async () => {
try {
// Use the globally available instantiateHeliaNode function
const helia = window.helia = await window.instantiateHeliaNode()
window.heliaFs = await HeliaUnixfs.unixfs(helia)
helia.libp2p.addEventListener('peer:discovery', (evt) => {
window.discoveredPeers.set(evt.detail.id.toString(), evt.detail)
addToLog(`Discovered peer ${evt.detail.id.toString()}`)
})
helia.libp2p.addEventListener('peer:connect', (evt) => {
addToLog(`Connected to ${evt.detail.toString()}`)
})
helia.libp2p.addEventListener('peer:disconnect', (evt) => {
addToLog(`Disconnected from ${evt.detail.toString()}`)
})
setInterval(() => {
const statusValueEl = document.getElementById('statusValue')
if (statusValueEl) {
statusValueEl.innerHTML = helia.libp2p.status === 'started' ? 'Online' : 'Offline'
}
updateConnectedPeers()
updateDiscoveredPeers()
}, 500)
const id = await helia.libp2p.peerId.toString()
const nodeIdEl = document.getElementById('nodeId')
if (nodeIdEl) {
nodeIdEl.innerHTML = id
}
addToLog('Helia node initialized successfully')
} catch (err) {
addToLog(`Error initializing Helia: ${err.message}`)
console.error('Error initializing Helia:', err)
}
})
</script>
}
}

View File

@@ -0,0 +1,60 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package helia
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
var heliaCardScriptHandle = templ.NewOnceHandle()
func ScriptTag() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script>\n document.addEventListener('DOMContentLoaded', async () => {\n try {\n // Use the globally available instantiateHeliaNode function\n const helia = window.helia = await window.instantiateHeliaNode()\n window.heliaFs = await HeliaUnixfs.unixfs(helia)\n\n helia.libp2p.addEventListener('peer:discovery', (evt) => {\n window.discoveredPeers.set(evt.detail.id.toString(), evt.detail)\n addToLog(`Discovered peer ${evt.detail.id.toString()}`)\n })\n\n helia.libp2p.addEventListener('peer:connect', (evt) => {\n addToLog(`Connected to ${evt.detail.toString()}`)\n })\n \n helia.libp2p.addEventListener('peer:disconnect', (evt) => {\n addToLog(`Disconnected from ${evt.detail.toString()}`)\n })\n\n setInterval(() => {\n const statusValueEl = document.getElementById('statusValue')\n if (statusValueEl) {\n statusValueEl.innerHTML = helia.libp2p.status === 'started' ? 'Online' : 'Offline'\n }\n updateConnectedPeers()\n updateDiscoveredPeers()\n }, 500)\n\n const id = await helia.libp2p.peerId.toString()\n const nodeIdEl = document.getElementById('nodeId')\n if (nodeIdEl) {\n nodeIdEl.innerHTML = id\n }\n addToLog('Helia node initialized successfully')\n } catch (err) {\n addToLog(`Error initializing Helia: ${err.message}`)\n console.error('Error initializing Helia:', err)\n }\n })\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = heliaCardScriptHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -44,7 +44,7 @@ func AreaChart(data []DateValue) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Date)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/area_chart.templ`, Line: 14, Col: 61}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/area_chart.templ`, Line: 14, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -57,7 +57,7 @@ func AreaChart(data []DateValue) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/area_chart.templ`, Line: 15, Col: 81}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/area_chart.templ`, Line: 15, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {

View File

@@ -45,7 +45,7 @@ func BarChart(data []KeyValue) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Key)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/bar_chart.templ`, Line: 15, Col: 60}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/bar_chart.templ`, Line: 15, Col: 60}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -58,7 +58,7 @@ func BarChart(data []KeyValue) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/bar_chart.templ`, Line: 16, Col: 81}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/bar_chart.templ`, Line: 16, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {

View File

@@ -39,7 +39,7 @@ func LineChart(data []DateValue) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Date)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/line_chart.templ`, Line: 9, Col: 61}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/line_chart.templ`, Line: 9, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -52,7 +52,7 @@ func LineChart(data []DateValue) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/line_chart.templ`, Line: 10, Col: 81}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/line_chart.templ`, Line: 10, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {

View File

@@ -46,7 +46,7 @@ func PieChart(data []CategoryValue) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Category)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/pie_chart.templ`, Line: 16, Col: 65}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/pie_chart.templ`, Line: 16, Col: 65}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -59,7 +59,7 @@ func PieChart(data []CategoryValue) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/charts/pie_chart.templ`, Line: 17, Col: 81}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/charts/pie_chart.templ`, Line: 17, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {

View File

@@ -36,7 +36,7 @@ func InputBio(value string, helpText string) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/inputs/input_bio.templ`, Line: 4, Col: 141}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/inputs/input_bio.templ`, Line: 4, Col: 141}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -49,7 +49,7 @@ func InputBio(value string, helpText string) templ.Component {
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(helpText)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/inputs/input_bio.templ`, Line: 4, Col: 164}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/inputs/input_bio.templ`, Line: 4, Col: 164}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {

View File

@@ -0,0 +1,34 @@
package inputs
templ HandleInitial() {
<div hx-target="this" hx-swap="outerHTML">
<label for="user-handle" class="block text-sm font-medium text-gray-300 mb-2">User Handle</label>
<sl-input size="large" name="handle" placeholder="digitalgold" type="text" minlength="4" maxlength="12" required hx-post="/register/profile" hx-indicator="#handle-indicator" autofocus>
<sl-icon class="p-0.5 ml-1.5" slot="prefix" name="at-sign" library="sonr"></sl-icon>
</sl-input>
</div>
<br/>
}
templ HandleError(value string, helpText string) {
<label for="user-handle" class="block text-sm font-medium text-gray-300 mb-2">User Handle</label>
<sl-input size="large" name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required class="border-red-500" value={ value } help-text={ helpText }>
<div slot="prefix">
<sl-icon name="at-sign" library="sonr"></sl-icon>
</div>
<div slot="suffix" style="color: #B54549;">
<sl-icon name="x"></sl-icon>
</div>
</sl-input>
<br/>
}
templ HandleSuccess(value string) {
<label for="user-handle" class="block text-sm font-medium text-gray-300 mb-2">User Handle</label>
<sl-input size="large" name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required class="border-green-500" value={ value } disabled>
<div slot="prefix" style="color: #46A758;">
<sl-icon name="at-sign" library="sonr"></sl-icon>
</div>
</sl-input>
<br/>
}

View File

@@ -29,7 +29,7 @@ func HandleInitial() templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div hx-target=\"this\" hx-swap=\"outerHTML\"><sl-input name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required hx-post=\"/register/profile\" hx-indicator=\"#handle-indicator\" autofocus><div slot=\"prefix\"><sl-icon name=\"at-sign\" library=\"sonr\"></sl-icon></div></sl-input></div><br>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div hx-target=\"this\" hx-swap=\"outerHTML\"><label for=\"user-handle\" class=\"block text-sm font-medium text-gray-300 mb-2\">User Handle</label> <sl-input size=\"large\" name=\"handle\" placeholder=\"digitalgold\" type=\"text\" minlength=\"4\" maxlength=\"12\" required hx-post=\"/register/profile\" hx-indicator=\"#handle-indicator\" autofocus><sl-icon class=\"p-0.5 ml-1.5\" slot=\"prefix\" name=\"at-sign\" library=\"sonr\"></sl-icon></sl-input></div><br>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -58,14 +58,14 @@ func HandleError(value string, helpText string) templ.Component {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<sl-input name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required class=\"border-red-500\" value=\"")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<label for=\"user-handle\" class=\"block text-sm font-medium text-gray-300 mb-2\">User Handle</label> <sl-input size=\"large\" name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required class=\"border-red-500\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/inputs/input_handle.templ`, Line: 15, Col: 152}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/inputs/input_handle.templ`, Line: 15, Col: 165}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
@@ -78,7 +78,7 @@ func HandleError(value string, helpText string) templ.Component {
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(helpText)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/inputs/input_handle.templ`, Line: 15, Col: 175}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/inputs/input_handle.templ`, Line: 15, Col: 188}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
@@ -113,14 +113,14 @@ func HandleSuccess(value string) templ.Component {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<sl-input name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required class=\"border-green-500\" value=\"")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<label for=\"user-handle\" class=\"block text-sm font-medium text-gray-300 mb-2\">User Handle</label> <sl-input size=\"large\" name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required class=\"border-green-500\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/inputs/input_handle.templ`, Line: 27, Col: 154}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/inputs/input_handle.templ`, Line: 28, Col: 167}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {

Some files were not shown because too many files have changed in this diff Show More