diff --git a/.million/store.json b/.million/store.json index aa73b3f..dea4f2b 100644 --- a/.million/store.json +++ b/.million/store.json @@ -1 +1 @@ -{"encodings":[],"reactData":{}} \ No newline at end of file +{"encodings":["src/components/Navigation.tsx","Navigation",[31,15,115,1],[32,19,32,32],[33,30,33,45],[34,38,34,53],[37,4,113,10],[43,6,61,12],[44,8,52,15],[53,8,60,17],[62,6,79,11],[64,10,77,15],[65,12,76,19],[66,14,75,23],[73,16,73,54],[80,6,112,12],[82,10,89,19],[87,12,87,47],[92,12,100,19],[93,14,99,23],[97,16,97,50],[101,12,109,19],[102,14,108,23],[106,16,106,53]],"reactData":{"src/components/Navigation.tsx":{"components":{"Navigation":{"loc":[31,15,115,1],"nameLoc":[31,24,31,34],"captures":[{"loc":[31,15,115,1],"kind":512},{"loc":[32,19,32,32],"kind":4},{"loc":[33,30,33,45],"kind":4},{"loc":[34,38,34,53],"kind":4},{"loc":[53,8,60,17],"kind":16},{"loc":[66,14,75,23],"kind":16},{"loc":[73,16,73,54],"kind":16},{"loc":[82,10,89,19],"kind":16},{"loc":[87,12,87,47],"kind":16},{"loc":[93,14,99,23],"kind":16},{"loc":[97,16,97,50],"kind":16},{"loc":[102,14,108,23],"kind":16},{"loc":[106,16,106,53],"kind":16}]}},"externals":[{"kind":"import","loc":[3,0,14,22]},{"kind":"import","loc":[15,0,15,29]},{"kind":"import","loc":[16,0,16,46]},{"kind":"import","loc":[17,0,17,33]},{"kind":"import","loc":[18,0,18,49]},{"kind":"import","loc":[19,0,19,34]},{"kind":"export","loc":[31,0,115,1]}]}}} \ No newline at end of file diff --git a/analyze/nodejs.html b/analyze/nodejs.html index 6213733..112a9df 100644 --- a/analyze/nodejs.html +++ b/analyze/nodejs.html @@ -3,7 +3,7 @@ - hackmit-2024 [15 Sep 2024 at 06:40] + fraud-guard-hackmit-2024 [28 Sep 2024 at 20:26] diff --git a/bun.lockb b/bun.lockb index b543fcb..032e178 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts new file mode 100644 index 0000000..54ce7f5 --- /dev/null +++ b/convex/_generated/api.d.ts @@ -0,0 +1,37 @@ +/* prettier-ignore-start */ + +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type { + ApiFromModules, + FilterApi, + FunctionReference, +} from "convex/server"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +declare const fullApi: ApiFromModules<{}>; +export declare const api: FilterApi< + typeof fullApi, + FunctionReference +>; +export declare const internal: FilterApi< + typeof fullApi, + FunctionReference +>; + +/* prettier-ignore-end */ diff --git a/convex/_generated/api.js b/convex/_generated/api.js new file mode 100644 index 0000000..b5f2e08 --- /dev/null +++ b/convex/_generated/api.js @@ -0,0 +1,26 @@ +/* prettier-ignore-start */ + +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { anyApi } from "convex/server"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +export const api = anyApi; +export const internal = anyApi; + +/* prettier-ignore-end */ diff --git a/convex/_generated/dataModel.d.ts b/convex/_generated/dataModel.d.ts new file mode 100644 index 0000000..4c7c9f8 --- /dev/null +++ b/convex/_generated/dataModel.d.ts @@ -0,0 +1,62 @@ +/* prettier-ignore-start */ + +/* eslint-disable */ +/** + * Generated data model types. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { AnyDataModel } from "convex/server"; +import type { GenericId } from "convex/values"; + +/** + * No `schema.ts` file found! + * + * This generated code has permissive types like `Doc = any` because + * Convex doesn't know your schema. If you'd like more type safety, see + * https://docs.convex.dev/using/schemas for instructions on how to add a + * schema file. + * + * After you change a schema, rerun codegen with `npx convex dev`. + */ + +/** + * The names of all of your Convex tables. + */ +export type TableNames = string; + +/** + * The type of a document stored in Convex. + */ +export type Doc = any; + +/** + * An identifier for a document in Convex. + * + * Convex documents are uniquely identified by their `Id`, which is accessible + * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). + * + * Documents can be loaded using `db.get(id)` in query and mutation functions. + * + * IDs are just strings at runtime, but this type can be used to distinguish them from other + * strings when type checking. + */ +export type Id = + GenericId; + +/** + * A type describing your Convex data model. + * + * This type includes information about what tables you have, the type of + * documents stored in those tables, and the indexes defined on them. + * + * This type is used to parameterize methods like `queryGeneric` and + * `mutationGeneric` to make them type-safe. + */ +export type DataModel = AnyDataModel; + +/* prettier-ignore-end */ diff --git a/convex/_generated/server.d.ts b/convex/_generated/server.d.ts new file mode 100644 index 0000000..8190e1f --- /dev/null +++ b/convex/_generated/server.d.ts @@ -0,0 +1,146 @@ +/* prettier-ignore-start */ + +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + ActionBuilder, + HttpActionBuilder, + MutationBuilder, + QueryBuilder, + GenericActionCtx, + GenericMutationCtx, + GenericQueryCtx, + GenericDatabaseReader, + GenericDatabaseWriter, +} from "convex/server"; +import type { DataModel } from "./dataModel.js"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const query: QueryBuilder; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const internalQuery: QueryBuilder; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const mutation: MutationBuilder; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const internalMutation: MutationBuilder; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export declare const action: ActionBuilder; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export declare const internalAction: ActionBuilder; + +/** + * Define an HTTP action. + * + * This function will be used to respond to HTTP requests received by a Convex + * deployment if the requests matches the path and method where this action + * is routed. Be sure to route your action in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. + */ +export declare const httpAction: HttpActionBuilder; + +/** + * A set of services for use within Convex query functions. + * + * The query context is passed as the first argument to any Convex query + * function run on the server. + * + * This differs from the {@link MutationCtx} because all of the services are + * read-only. + */ +export type QueryCtx = GenericQueryCtx; + +/** + * A set of services for use within Convex mutation functions. + * + * The mutation context is passed as the first argument to any Convex mutation + * function run on the server. + */ +export type MutationCtx = GenericMutationCtx; + +/** + * A set of services for use within Convex action functions. + * + * The action context is passed as the first argument to any Convex action + * function run on the server. + */ +export type ActionCtx = GenericActionCtx; + +/** + * An interface to read from the database within Convex query functions. + * + * The two entry points are {@link DatabaseReader.get}, which fetches a single + * document by its {@link Id}, or {@link DatabaseReader.query}, which starts + * building a query. + */ +export type DatabaseReader = GenericDatabaseReader; + +/** + * An interface to read from and write to the database within Convex mutation + * functions. + * + * Convex guarantees that all writes within a single mutation are + * executed atomically, so you never have to worry about partial writes leaving + * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) + * for the guarantees Convex provides your functions. + */ +export type DatabaseWriter = GenericDatabaseWriter; + +/* prettier-ignore-end */ diff --git a/convex/_generated/server.js b/convex/_generated/server.js new file mode 100644 index 0000000..33b487c --- /dev/null +++ b/convex/_generated/server.js @@ -0,0 +1,93 @@ +/* prettier-ignore-start */ + +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + actionGeneric, + httpActionGeneric, + queryGeneric, + mutationGeneric, + internalActionGeneric, + internalMutationGeneric, + internalQueryGeneric, +} from "convex/server"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const query = queryGeneric; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const internalQuery = internalQueryGeneric; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const mutation = mutationGeneric; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const internalMutation = internalMutationGeneric; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export const action = actionGeneric; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export const internalAction = internalActionGeneric; + +/** + * Define a Convex HTTP action. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument, and a `Request` object + * as its second. + * @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`. + */ +export const httpAction = httpActionGeneric; + +/* prettier-ignore-end */ diff --git a/next.config.mjs b/next.config.mjs index b8a0f74..0dfe1dd 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -2,6 +2,7 @@ import pwa from '@ducanh2912/next-pwa'; import MillionLint from '@million/lint'; import withBundleAnalyzer from '@next/bundle-analyzer'; import { withSentryConfig } from '@sentry/nextjs'; +import withPlugins from 'next-compose-plugins'; const withPwa = pwa({ dest: 'public', @@ -45,6 +46,12 @@ const config = { { protocol: 'https', hostname: 'lh3.googleusercontent.com' }, { protocol: 'http', hostname: 'localhost', port: '3000' }, { protocol: 'https', hostname: 'encrypted-tbn0.gstatic.com' }, + { + protocol: 'https', + hostname: 'hebbkx1anhila5yf.public.blob.vercel-storage.com', + port: '', // Leave empty for default ports (80 for http, 443 for https) + pathname: '/**', // Allow all paths under this hostname + }, ], }, rewrites() { @@ -60,7 +67,10 @@ const config = { { source: '/api/v1/:path*', headers: [ - { key: 'Access-Control-Allow-Credentials', value: 'true' }, + { + key: 'Access-Control-Allow-Credentials', + value: 'true' + }, { key: 'Access-Control-Allow-Origin', value: 'https://full-stack-template.vercel.app' }, { key: 'Access-Control-Allow-Methods', @@ -112,11 +122,12 @@ const withMillion = MillionLint.next({ }) const finalConfig = withPlugins([ - [withBundleAnalyzer({ enabled: process.env.ANALYZE })], + [withBundleAnalyzer({ enabled: false })], [pwa], [withMillion], ], config) + export default withSentryConfig(finalConfig, { org: 'womb0comb0', project: 'fraud-guard', @@ -130,4 +141,4 @@ export default withSentryConfig(finalConfig, { hideSourceMaps: true, disableLogger: true, automaticVercelMonitors: true, -}); +}); \ No newline at end of file diff --git a/package.json b/package.json index 226058f..ee46f02 100644 --- a/package.json +++ b/package.json @@ -72,10 +72,15 @@ "@radix-ui/react-toast": "^1.2.1", "@radix-ui/react-toggle": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.2", + "@sentry/nextjs": "^8", + "@tailwindcss/typography": "^0.5.15", + "@tanstack/react-query-devtools": "^5.58.0", "@types/node": "22.7.4", "@types/react": "18.3.10", "@types/react-dom": "18.3.0", + "@vercel/analytics": "^1.3.1", "@vercel/otel": "^1.10.0", + "@vercel/speed-insights": "^1.0.12", "autoprefixer": "10.4.20", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -98,10 +103,13 @@ "react-hook-form": "^7.53.0", "react-remove-scroll": "^2.6.0", "recharts": "^2.12.7", + "sonner": "^1.5.0", + "superjson": "^2.2.1", "tailwind-merge": "^2.5.2", "tailwindcss": "3.4.13", "tailwindcss-animate": "^1.0.7", "typescript": "5.6.2", + "usehooks-ts": "^3.1.0", "zod": "^3.23.8" }, "devDependencies": { diff --git a/sentry.client.config.ts b/sentry.client.config.ts index d9c37dc..e370570 100644 --- a/sentry.client.config.ts +++ b/sentry.client.config.ts @@ -2,29 +2,27 @@ // The config you add here will be used whenever a users loads a page in their browser. // https://docs.sentry.io/platforms/javascript/guides/nextjs/ -import * as Sentry from '@sentry/nextjs'; +import * as Sentry from "@sentry/nextjs"; Sentry.init({ - dsn: 'https://0bf0a87a46e99350888414e16ab9f36f@o4506762839916544.ingest.us.sentry.io/4506762870128640', + dsn: "https://0dd166b1e970307a6ddaa67619d49310@o4506762839916544.ingest.us.sentry.io/4508032554303488", - // Adjust this value in production, or use tracesSampler for greater control - tracesSampleRate: 1, - - // Setting this option to true will print useful information to the console while you're setting up Sentry. - debug: false, + // Add optional integrations for additional features + integrations: [ + Sentry.replayIntegration(), + ], - replaysOnErrorSampleRate: 1.0, + // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. + tracesSampleRate: 1, + // Define how likely Replay events are sampled. // This sets the sample rate to be 10%. You may want this to be 100% while // in development and sample at a lower rate in production replaysSessionSampleRate: 0.1, - // You can remove this option if you're not planning to use the Sentry Session Replay feature: - integrations: [ - Sentry.replayIntegration({ - // Additional Replay configuration goes in here, for example: - maskAllText: true, - blockAllMedia: true, - }), - ], + // Define how likely Replay events are sampled when an error occurs. + replaysOnErrorSampleRate: 1.0, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: false, }); diff --git a/sentry.edge.config.ts b/sentry.edge.config.ts index b4bae18..1d44927 100644 --- a/sentry.edge.config.ts +++ b/sentry.edge.config.ts @@ -3,12 +3,12 @@ // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally. // https://docs.sentry.io/platforms/javascript/guides/nextjs/ -import * as Sentry from '@sentry/nextjs'; +import * as Sentry from "@sentry/nextjs"; Sentry.init({ - dsn: 'https://0bf0a87a46e99350888414e16ab9f36f@o4506762839916544.ingest.us.sentry.io/4506762870128640', + dsn: "https://0dd166b1e970307a6ddaa67619d49310@o4506762839916544.ingest.us.sentry.io/4508032554303488", - // Adjust this value in production, or use tracesSampler for greater control + // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. tracesSampleRate: 1, // Setting this option to true will print useful information to the console while you're setting up Sentry. diff --git a/sentry.server.config.ts b/sentry.server.config.ts index 6696899..2377a20 100644 --- a/sentry.server.config.ts +++ b/sentry.server.config.ts @@ -2,17 +2,14 @@ // The config you add here will be used whenever the server handles a request. // https://docs.sentry.io/platforms/javascript/guides/nextjs/ -import * as Sentry from '@sentry/nextjs'; +import * as Sentry from "@sentry/nextjs"; Sentry.init({ - dsn: 'https://0bf0a87a46e99350888414e16ab9f36f@o4506762839916544.ingest.us.sentry.io/4506762870128640', + dsn: "https://0dd166b1e970307a6ddaa67619d49310@o4506762839916544.ingest.us.sentry.io/4508032554303488", - // Adjust this value in production, or use tracesSampler for greater control + // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. tracesSampleRate: 1, // Setting this option to true will print useful information to the console while you're setting up Sentry. debug: false, - - // Uncomment the line below to enable Spotlight (https://spotlightjs.com) - // spotlight: process.env.NODE_ENV === 'development', }); diff --git a/src/app/loading.tsx b/src/app/loading.tsx index 10489d5..0eaa6f0 100644 --- a/src/app/loading.tsx +++ b/src/app/loading.tsx @@ -1,19 +1,11 @@ 'use client'; -import Particles from '@/components/magicui/particles'; -import Image from 'next/image'; import React from 'react'; +import Image from 'next/image'; const Loading = React.memo(() => { return (
-
@@ -26,68 +18,6 @@ const Loading = React.memo(() => { />
-
); }); diff --git a/src/app/page.tsx b/src/app/page.tsx index 8580506..48d2c44 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -22,14 +22,14 @@ import { TabsList, TabsTrigger, } from "../components/ui/tabs"; -import { useIsomorphicLayout } from 'usehooks-ts' +import { useIsomorphicLayoutEffect } from 'usehooks-ts' export default function LandingPage() { const [isLogin, setIsLogin] = useState(true); const router = useRouter(); const [mounted, setMounted] = useState(false); - useIsomorphicLayout(() => { + useIsomorphicLayoutEffect(() => { setMounted(true); }, []); diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx new file mode 100644 index 0000000..452f4d9 --- /dev/null +++ b/src/components/ui/sonner.tsx @@ -0,0 +1,31 @@ +"use client" + +import { useTheme } from "next-themes" +import { Toaster as Sonner } from "sonner" + +type ToasterProps = React.ComponentProps + +const Toaster = ({ ...props }: ToasterProps) => { + const { theme = "system" } = useTheme() + + return ( + + ) +} + +export { Toaster } diff --git a/src/instrumentation.ts b/src/instrumentation.ts index efd3d32..f86734d 100644 --- a/src/instrumentation.ts +++ b/src/instrumentation.ts @@ -2,4 +2,12 @@ import { registerOTel } from "@vercel/otel" export const register = async () => { registerOTel({ serviceName: "fraud-guard-hackmit-2024" }) + + if (process.env.NEXT_RUNTIME === 'nodejs') { + await import('../sentry.server.config'); + } + + if (process.env.NEXT_RUNTIME === 'edge') { + await import('../sentry.edge.config'); + } } \ No newline at end of file