mirror of
https://github.com/hanzoai/ads.git
synced 2026-09-30 20:39:45 +00:00
The ad plane at api.hanzo.ai/v1/ad had no screen of its own. This adds one beside the Go module, built the same way as Hanzo Social: campaigns with their totals, a campaign to launch, pause, edit or delete, ad accounts connected through /v1/integration, and spend against budget. It shows only what the API returns, so there is no targeting, creative or delivery data to draw. Co-authored-by: Hanzo Dev <[email protected]>
54 lines
2.0 KiB
HTML
54 lines
2.0 KiB
HTML
<!doctype html>
|
|
<html lang="en" data-theme="dark">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<base href="/" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="color-scheme" content="dark light" />
|
|
<title>Hanzo Ads</title>
|
|
<meta
|
|
name="description"
|
|
content="Plan paid campaigns, launch them on their network, and keep budget and spend in one place."
|
|
/>
|
|
<style>
|
|
/* The two things only the host document can answer: how tall the app is,
|
|
and that its one child is a flex item. @hanzo/ui's stylesheet resets and
|
|
paints everything else. Without this the app grows to fit its content
|
|
instead of filling the window, and every pane that scrolls inside it
|
|
scrolls the page instead. */
|
|
#root {
|
|
display: flex;
|
|
height: 100dvh;
|
|
}
|
|
</style>
|
|
<script>
|
|
/* Keep gui's theme class in step with next-themes'. One decision, two
|
|
names: next-themes writes `light` on <html> and gui reads `t_light` /
|
|
`t_dark`, so without this the account's choice moves one of them and the
|
|
page stays painted the other way.
|
|
|
|
`was` is not an optimisation — a `classList.toggle` that changes nothing
|
|
still writes the attribute, and an observer reacting to its own write is
|
|
a loop. Comparing first makes the callback a no-op unless the theme
|
|
moved. Inline and in <head>, because the first paint happens before any
|
|
module runs. */
|
|
;(function () {
|
|
var e = document.documentElement, was
|
|
function s() {
|
|
var l = e.classList.contains('light')
|
|
if (l === was) return
|
|
was = l
|
|
e.classList.toggle('t_light', l)
|
|
e.classList.toggle('t_dark', !l)
|
|
}
|
|
s()
|
|
new MutationObserver(s).observe(e, { attributes: true, attributeFilter: ['class'] })
|
|
})()
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
<script type="module" src="/src/main.tsx"></script>
|
|
</body>
|
|
</html>
|