Skip to content

Commit 00427bc

Browse files
committed
feat: deploy dashboard
1 parent 4104f89 commit 00427bc

File tree

18 files changed

+227
-302
lines changed

18 files changed

+227
-302
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
node_modules
22
docs
33

4-
.DS_Store
4+
.DS_Store
5+
# Local Netlify folder
6+
.netlify

examples/example-vite-kitchen-sink/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
# testing
1010
/coverage
11+
/dist/
1112

1213
# next.js
1314
/.next/
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# example netlify.toml
2+
[build]
3+
command = "pnpm run build"
4+
functions = "netlify/functions"
5+
publish = "examples/example-vite-kitchen-sink/dist"
6+
7+
## Uncomment to use this redirect for Single Page Applications like create-react-app.
8+
## Not needed for static site generators.
9+
#[[redirects]]
10+
# from = "/*"
11+
# to = "/index.html"
12+
# status = 200
13+
14+
## (optional) Settings for Netlify Dev
15+
## https://github.com/netlify/cli/blob/main/docs/netlify-dev.md#project-detection
16+
#[dev]
17+
# command = "yarn start" # Command to start your dev server
18+
# port = 3000 # Port that the dev server will be listening on
19+
# publish = "dist" # Folder with the static content for _redirect file
20+
21+
## more info on configuring this file: https://ntl.fyi/file-based-build-config

examples/example-vite-kitchen-sink/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
"@cartridge/connector": "^0.3.46",
1313
"@dojoengine/core": "workspace:*",
1414
"@dojoengine/sdk": "workspace:*",
15+
"@dojoengine/torii-wasm": "workspace:*",
16+
"@dojoengine/torii-client": "workspace:*",
1517
"@radix-ui/react-dialog": "^1.1.1",
1618
"@radix-ui/react-dropdown-menu": "^2.1.1",
1719
"@radix-ui/react-icons": "^1.3.0",

examples/example-vite-kitchen-sink/src/app/layout.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ import Header from "@/components/header";
55
import StarknetProvider from "@/components/starknet-provider";
66

77

8-
export default function RootLayout({ children }) {
8+
export default function RootLayout({ children }: React.PropsWithChildren<{}>) {
99
return (
1010
<StarknetProvider>
11-
<TooltipProvider delayDuration={400}>
12-
<div className="grid h-screen w-full pl-[53px]">
13-
<Sidebar />
14-
<div className="flex flex-col">
15-
<Header />
16-
{children}
17-
</div>
11+
<TooltipProvider delayDuration={400}>
12+
<div className="grid h-screen w-full pl-[53px]">
13+
<Sidebar />
14+
<div className="flex flex-col">
15+
<Header />
16+
{children}
1817
</div>
19-
</TooltipProvider>
18+
</div>
19+
</TooltipProvider>
2020
</StarknetProvider>
2121
);
2222
}

examples/example-vite-kitchen-sink/src/components/caller-counter.tsx

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import { dojoConfig } from "@/dojo.config";
1010

1111
export default function CallerCounter() {
1212
const [count, setCount] = useState(0);
13-
const [sub, setSub] = useState<Subscription>(null);
13+
const [isLoading, setIsLoading] = useState(false);
14+
const [sub, setSub] = useState<Subscription | null>(null);
1415
const { address } = useAccount();
1516
const { write: incrementCallerCounter } = useContractWrite({
1617
calls: [{
@@ -22,7 +23,8 @@ export default function CallerCounter() {
2223

2324
const handleCallerClick = useCallback(async () => {
2425
incrementCallerCounter();
25-
}, [incrementCallerCounter]);
26+
setIsLoading(true);
27+
}, [incrementCallerCounter, setIsLoading]);
2628

2729
const db = useDojoDb();
2830
useEffect(() => {
@@ -31,13 +33,17 @@ export default function CallerCounter() {
3133
onchain_dash: {
3234
CallerCounter: { $: { where: { caller: { $eq: ensureStarkFelt(address) } } } }
3335
}
34-
}, ({ data, error }) => { });
36+
}, () => { });
3537
const counter = entity.pop();
3638
if (!counter) {
3739
return 0;
3840
}
39-
const count = parseInt(counter.models.onchain_dash.CallerCounter.counter, 16);
40-
return count;
41+
const count = counter.models.onchain_dash?.CallerCounter?.counter
42+
if (undefined === count) {
43+
return 0;
44+
}
45+
46+
return parseInt(count.toString(), 16);
4147
}
4248
if (address && db) {
4349
getEntity(db, address).then(setCount).catch(console.error)
@@ -47,6 +53,7 @@ export default function CallerCounter() {
4753
useEffect(() => {
4854
async function subscribeToEntityUpdates(db: SDK<OnchainDashSchemaType>, address: string) {
4955
const sub = await db.subscribeEntityQuery({
56+
// @ts-expect-error $eq is working there
5057
onchain_dash: { CallerCounter: { $: { where: { caller: { $eq: ensureStarkFelt(address) } } } } }
5158
}, ({ data, error }) => {
5259
if (data) {
@@ -57,8 +64,13 @@ export default function CallerCounter() {
5764
if (entity.models.onchain_dash?.CallerCounter?.counter === undefined) {
5865
return
5966
}
60-
const count = parseInt(entity.models.onchain_dash?.CallerCounter?.counter, 16);
61-
setCount(count);
67+
const count = entity.models.onchain_dash?.CallerCounter?.counter;
68+
if (undefined === count) {
69+
return 0;
70+
}
71+
72+
setIsLoading(false);
73+
setCount(parseInt(count.toString(), 16));
6274
return;
6375
}
6476
if (error) {
@@ -85,7 +97,7 @@ export default function CallerCounter() {
8597
Count : {count}
8698
</div>
8799
<div className="grid gap-3">
88-
<Button variant="outline" className="rounded-lg" onClick={handleCallerClick}>Click me !</Button>
100+
<Button variant="outline" className="rounded-lg" loading={isLoading} onClick={handleCallerClick}>Click me !</Button>
89101
</div>
90102
</fieldset>
91103

examples/example-vite-kitchen-sink/src/components/chat.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useDojoDb } from "@/dojo/provider";
99
import { useAccount } from "@starknet-react/core";
1010
import { toValidAscii } from "@/lib/utils";
1111
import { SDK } from "@dojoengine/sdk";
12-
import { OnchainDashSchemaType } from "@/dojo/models";
12+
import { Message, OnchainDashSchemaType } from "@/dojo/models";
1313
import { Subscription } from "@dojoengine/torii-wasm";
1414
import { shortAddress } from "@/lib/utils";
1515

@@ -19,15 +19,19 @@ interface MessageItem {
1919
timestamp: number;
2020
}
2121

22+
interface FormValues {
23+
message: string;
24+
}
25+
2226
export default function Chat() {
23-
const { register, handleSubmit, reset } = useForm();
27+
const { register, handleSubmit, reset } = useForm<FormValues>();
2428
const { account } = useAccount();
2529
const [messages, setMessages] = useState<MessageItem[]>([]);
26-
const [sub, setSub] = useState<Subscription>(null);
30+
const [sub, setSub] = useState<Subscription | null>(null);
2731
const formRef = useRef<HTMLFormElement>(null);
2832

2933
const db = useDojoDb();
30-
const publish = useCallback(async (data) => {
34+
const publish = useCallback(async (data: FormValues) => {
3135
if (!account || !db) return;
3236

3337
const asciiMessage = toValidAscii(data.message);
@@ -36,7 +40,7 @@ export default function Chat() {
3640
const signature = await account.signMessage(msg);
3741

3842
try {
39-
await db.client.publishMessage(JSON.stringify(msg), signature);
43+
await db.client.publishMessage(JSON.stringify(msg), signature as string[]);
4044
reset();
4145
} catch (error) {
4246
console.error("failed to publish message:", error);
@@ -50,11 +54,13 @@ export default function Chat() {
5054
async function getEntity(db: SDK<OnchainDashSchemaType>) {
5155
const entity = await db.getEntities({
5256
onchain_dash: { Message: { $: {} } }
53-
}, ({ data, error }) => { });
57+
}, () => { });
5458

55-
return entity.map(e => e.models.onchain_dash.Message).filter(Boolean).sort((a, b) => parseInt(a.timestamp, 16) < parseInt(b.timestamp, 16) ? -1 : 1);
59+
// @ts-expect-error a & b are not undefined as they are filtered out with `filer(Boolean)`
60+
return entity.map(e => e.models.onchain_dash.Message).filter(Boolean).sort((a: Message, b: Message): number => parseInt(a.timestamp.toString(), 16) < parseInt(b.timestamp.toString(), 16) ? -1 : 1);
5661
}
5762
if (db && messages.length === 0 && sub === null) {
63+
// @ts-expect-error ts is getting drunk there
5864
getEntity(db).then(setMessages).catch(console.error)
5965
}
6066
}, [db, messages, sub])
@@ -63,7 +69,7 @@ export default function Chat() {
6369
async function subscribeToEntityUpdates(db: SDK<OnchainDashSchemaType>) {
6470
const sub = await db.subscribeEntityQuery({
6571
onchain_dash: { Message: { $: {} } }
66-
}, ({ data, error }) => {
72+
}, ({ data }) => {
6773
if (data) {
6874
const entity = data.pop();
6975
if (!entity) {
@@ -83,7 +89,7 @@ export default function Chat() {
8389
}
8490
}, [db, sub, setMessages]);
8591

86-
const handleKeyPress = useCallback((e: KeyboardEvent<HTMLInputElement>) => {
92+
const handleKeyPress = useCallback((e: KeyboardEvent<HTMLFormElement>) => {
8793
if (e.key !== 'Enter') {
8894
return;
8995
}

examples/example-vite-kitchen-sink/src/components/global-counter.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { dojoConfig } from "@/dojo.config";
99

1010
export default function GlobalCOunter() {
1111
const [count, setCount] = useState(0);
12-
const [sub, setSub] = useState<Subscription>(null);
12+
const [isLoading, setIsLoading] = useState(false);
13+
const [sub, setSub] = useState<Subscription | null>(null);
1314
const { write: incrementGlobalCounter } = useContractWrite({
1415
calls: [{
1516
contractAddress: dojoConfig.manifest.contracts[0].address,
@@ -19,7 +20,8 @@ export default function GlobalCOunter() {
1920
});
2021
const handleGlobalClick = useCallback(async () => {
2122
incrementGlobalCounter();
22-
}, [incrementGlobalCounter]);
23+
setIsLoading(true);
24+
}, [incrementGlobalCounter, setIsLoading]);
2325

2426
const db = useDojoDb();
2527

@@ -35,8 +37,11 @@ export default function GlobalCOunter() {
3537
if (!counter) {
3638
return 0;
3739
}
38-
const count = parseInt(counter.models.onchain_dash.GlobalCounter.counter, 16);
39-
return count;
40+
const count = counter.models.onchain_dash?.GlobalCounter?.counter;
41+
if (undefined === count) {
42+
return 0;
43+
}
44+
return parseInt(count.toString(), 16);
4045
}
4146

4247
if (db) {
@@ -47,6 +52,7 @@ export default function GlobalCOunter() {
4752
useEffect(() => {
4853
async function subscribeToEntityUpdates(db: SDK<OnchainDashSchemaType>) {
4954
const sub = await db.subscribeEntityQuery({
55+
// @ts-expect-error $eq is working there
5056
onchain_dash: { GlobalCounter: { $: { where: { global_counter_key: { $eq: 9999999 } } } } }
5157
}, ({ data, error }) => {
5258
if (data) {
@@ -57,8 +63,13 @@ export default function GlobalCOunter() {
5763
if (entity.models.onchain_dash?.GlobalCounter?.counter === undefined) {
5864
return
5965
}
60-
const count = parseInt(entity.models.onchain_dash?.GlobalCounter?.counter, 16);
61-
setCount(count);
66+
const count = entity.models.onchain_dash?.GlobalCounter?.counter;
67+
if (undefined === count) {
68+
return 0;
69+
}
70+
const value = parseInt(count.toString(), 16);
71+
setCount(value);
72+
setIsLoading(false);
6273
return;
6374
}
6475
if (error) {
@@ -75,7 +86,7 @@ export default function GlobalCOunter() {
7586
sub.free();
7687
}
7788
};
78-
}, [db, sub]);
89+
}, [db, sub, setIsLoading]);
7990

8091
return (
8192
<fieldset className="grid gap-6 rounded-lg border p-4">
@@ -86,7 +97,7 @@ export default function GlobalCOunter() {
8697
Count : {count}
8798
</div>
8899
<div className="grid gap-3">
89-
<Button variant="outline" className="rounded-lg" onClick={handleGlobalClick}>Click me !</Button>
100+
<Button variant="outline" className="rounded-lg" loading={isLoading} onClick={handleGlobalClick}>Click me !</Button>
90101
</div>
91102
</fieldset>
92103
)

0 commit comments

Comments
 (0)