clerk
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
110
package-lock.json
generated
110
package-lock.json
generated
@@ -8,6 +8,7 @@
|
||||
"name": "vite-react-typescript-starter",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@clerk/clerk-react": "^5.38.1",
|
||||
"lucide-react": "^0.344.0",
|
||||
"partykit": "^0.0.115",
|
||||
"partysocket": "^1.1.4",
|
||||
@@ -347,6 +348,66 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@clerk/clerk-react": {
|
||||
"version": "5.38.1",
|
||||
"resolved": "https://registry.npmjs.org/@clerk/clerk-react/-/clerk-react-5.38.1.tgz",
|
||||
"integrity": "sha512-IOn/Raet3jwkug8P/gLMe2nsw2wKllWGOGPFOAaaYxbXfIZ8MPngNv2/MMgVRF7cAX1UwrmU1PzrLNtBJ/EHPQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clerk/shared": "^3.17.0",
|
||||
"@clerk/types": "^4.72.0",
|
||||
"tslib": "2.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@clerk/shared": {
|
||||
"version": "3.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-3.17.0.tgz",
|
||||
"integrity": "sha512-eYbA0xmKG1DluFmdVykXiElgZGTpCruEyXmIBAwokpxypd5nOpDsS1xvEKwYvZieLTZkFz21Z3Y6HdDI5cPxBQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clerk/types": "^4.72.0",
|
||||
"dequal": "2.0.3",
|
||||
"glob-to-regexp": "0.4.1",
|
||||
"js-cookie": "3.0.5",
|
||||
"std-env": "^3.9.0",
|
||||
"swr": "2.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@clerk/types": {
|
||||
"version": "4.72.0",
|
||||
"resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.72.0.tgz",
|
||||
"integrity": "sha512-SEkgiQNeTstC0/mQjHCGBEyX0/ALyWAa5QZBBvVOok204r48MLipfIKsXQhyWE2Hk6FIo5WT6YyqD36jaxUEIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"csstype": "3.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cloudflare/workerd-darwin-64": {
|
||||
"version": "1.20240718.0",
|
||||
"resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240718.0.tgz",
|
||||
@@ -2040,8 +2101,7 @@
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/data-uri-to-buffer": {
|
||||
"version": "2.0.2",
|
||||
@@ -2077,6 +2137,15 @@
|
||||
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/didyoumean": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||
@@ -2963,6 +3032,15 @@
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
},
|
||||
"node_modules/js-cookie": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
|
||||
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@@ -3963,6 +4041,12 @@
|
||||
"get-source": "^2.0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/std-env": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
|
||||
"integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stoppable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
|
||||
@@ -4139,6 +4223,19 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/swr": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/swr/-/swr-2.3.4.tgz",
|
||||
"integrity": "sha512-bYd2lrhc+VarcpkgWclcUi92wYCpOgMws9Sd1hG1ntAu0NEy+14CbotuFjshBU2kt9rYj9TSmDcybpxpeTU1fg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/system-architecture": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/system-architecture/-/system-architecture-0.1.0.tgz",
|
||||
@@ -4387,6 +4484,15 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-sync-external-store": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
|
||||
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@clerk/clerk-react": "^5.38.1",
|
||||
"lucide-react": "^0.344.0",
|
||||
"partykit": "^0.0.115",
|
||||
"partysocket": "^1.1.4",
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import type * as Party from 'partykit/server';
|
||||
|
||||
interface GameState {
|
||||
totalClicks: number;
|
||||
users: Record<string, { name: string; clicks: number; lastSeen: number }>;
|
||||
@@ -65,11 +68,11 @@ export default class GameServer implements Party.Server {
|
||||
|
||||
autoClickInterval?: NodeJS.Timeout;
|
||||
|
||||
onConnect(conn: Party.Connection, ctx: Party.ConnectionContext) {
|
||||
onConnect(conn: Party.Connection, _ctx: Party.ConnectionContext) {
|
||||
conn.send(JSON.stringify({ type: 'game-state', state: this.gameState }));
|
||||
}
|
||||
|
||||
onMessage(message: string, sender: Party.Connection) {
|
||||
onMessage(message: string, _sender: Party.Connection) {
|
||||
const data = JSON.parse(message) as Message;
|
||||
|
||||
switch (data.type) {
|
||||
@@ -140,10 +143,10 @@ export default class GameServer implements Party.Server {
|
||||
|
||||
Object.entries(this.gameState.upgrades).forEach(([upgradeId, upgrade]) => {
|
||||
const config = UPGRADES[upgradeId as keyof typeof UPGRADES];
|
||||
if (config.clickBonus) {
|
||||
if ('clickBonus' in config && config.clickBonus) {
|
||||
this.gameState.clickMultiplier += config.clickBonus * upgrade.owned;
|
||||
}
|
||||
if (config.autoClickRate) {
|
||||
if ('autoClickRate' in config && config.autoClickRate) {
|
||||
this.gameState.autoClickRate += config.autoClickRate * upgrade.owned;
|
||||
}
|
||||
});
|
||||
|
||||
24
src/App.tsx
24
src/App.tsx
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { usePartyKit } from './hooks/usePartyKit';
|
||||
import { ClickButton } from './components/ClickButton';
|
||||
import { Counter } from './components/Counter';
|
||||
@@ -7,6 +7,7 @@ import { Milestones } from './components/Milestones';
|
||||
import { Leaderboard } from './components/Leaderboard';
|
||||
import { Background } from './components/Background';
|
||||
import { MILESTONES } from './config/milestones';
|
||||
import { SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/clerk-react';
|
||||
|
||||
function App() {
|
||||
const { gameState, sendClick, purchaseUpgrade, userId } = usePartyKit();
|
||||
@@ -50,6 +51,13 @@ function App() {
|
||||
<div className="min-h-screen relative overflow-x-hidden">
|
||||
<Background background={gameState.currentBackground} />
|
||||
|
||||
{/* User Button */}
|
||||
<div className="absolute top-4 right-4 z-50">
|
||||
<SignedIn>
|
||||
<UserButton />
|
||||
</SignedIn>
|
||||
</div>
|
||||
|
||||
{/* Celebration Message */}
|
||||
{celebrationMessage && (
|
||||
<div className="fixed top-0 left-0 right-0 z-50 flex justify-center pt-8">
|
||||
@@ -125,6 +133,20 @@ function App() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* If not logged in, show popup overlaying the game to login */}
|
||||
<SignedOut>
|
||||
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
|
||||
<div className="bg-white p-8 rounded-lg shadow-lg text-center">
|
||||
<h2 className="text-2xl font-bold mb-4">Welcome to Bozo Clicker!</h2>
|
||||
<p className="mb-6">Please sign in to start clicking!</p>
|
||||
<SignInButton mode="modal">
|
||||
<button className="bg-blue-500 text-white px-6 py-2 rounded-lg hover:bg-blue-600 transition">
|
||||
Sign In
|
||||
</button>
|
||||
</SignInButton>
|
||||
</div>
|
||||
</div>
|
||||
</SignedOut>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState, useEffect, useCallback } from 'react';
|
||||
import PartySocket from 'partysocket';
|
||||
import { GameState } from '../types';
|
||||
|
||||
const PARTY_HOST = import.meta.env.DEV ? 'localhost:1998' : 'bozo-clicker.your-username.partykit.dev';
|
||||
const PARTY_HOST = import.meta.env.DEV ? 'localhost:1999' : 'bozo-clicker.your-username.partykit.dev';
|
||||
|
||||
export function usePartyKit() {
|
||||
const [gameState, setGameState] = useState<GameState | null>(null);
|
||||
|
||||
@@ -2,9 +2,18 @@ import { StrictMode } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
import { ClerkProvider } from '@clerk/clerk-react'
|
||||
|
||||
// Import your Publishable Key
|
||||
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY
|
||||
|
||||
if (!PUBLISHABLE_KEY) {
|
||||
throw new Error('Missing Publishable Key')
|
||||
}
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<ClerkProvider publishableKey={PUBLISHABLE_KEY}>
|
||||
<App />
|
||||
</ClerkProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
12
todo.md
Normal file
12
todo.md
Normal file
@@ -0,0 +1,12 @@
|
||||
Basically add things from <https://neal.fun/stimulation-clicker/>
|
||||
|
||||
thewre should be an news section available as redeemable using clicks with fun news titles
|
||||
|
||||
Dylan the Diabolical Dutchman
|
||||
[BOZO]
|
||||
— 00:00
|
||||
Like, at first it's only a bozo you click, after a while, codebugs pop up as bonuses, later, you can combo codebugs and shoominions as they pop up. Later, you get a mascot storm, where mascots of all types fly over the screen from left to right, and you have to click as many as possible.
|
||||
|
||||
And some more
|
||||
|
||||
Auth integration not completed with clerk, needs partykit to be integrated with clerk
|
||||
Reference in New Issue
Block a user