Skip to content

Commit

Permalink
chore: Add minimal-tanstack-start
Browse files Browse the repository at this point in the history
  • Loading branch information
juraj98 committed Sep 25, 2024
1 parent e48abf5 commit ce3cf96
Show file tree
Hide file tree
Showing 15 changed files with 2,445 additions and 62 deletions.
2 changes: 2 additions & 0 deletions examples/minimal-tanstack-start/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Go to https://uploadthing.com/dashboard to get your token
UPLOADTHING_TOKEN='...'
3 changes: 3 additions & 0 deletions examples/minimal-tanstack-start/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { defineConfig } from "@tanstack/start/config";

export default defineConfig({});
6 changes: 6 additions & 0 deletions examples/minimal-tanstack-start/app/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {
createStartAPIHandler,
defaultAPIFileRouteHandler,
} from "@tanstack/start/api";

export default createStartAPIHandler(defaultAPIFileRouteHandler);
8 changes: 8 additions & 0 deletions examples/minimal-tanstack-start/app/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// app/client.tsx
import { hydrateRoot } from "react-dom/client";
import { StartClient } from "@tanstack/start";
import { createRouter } from "./router";

const router = createRouter();

hydrateRoot(document.getElementById("root")!, <StartClient router={router} />);
89 changes: 89 additions & 0 deletions examples/minimal-tanstack-start/app/routeTree.gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* prettier-ignore-start */

/* eslint-disable */

// @ts-nocheck

// noinspection JSUnusedGlobalSymbols

// This file is auto-generated by TanStack Router

// Import Routes

import { Route as rootRoute } from "./routes/__root";
import { Route as IndexImport } from "./routes/index";

// Create/Update Routes

const IndexRoute = IndexImport.update({
path: "/",
getParentRoute: () => rootRoute,
} as any);

// Populate the FileRoutesByPath interface

declare module "@tanstack/react-router" {
interface FileRoutesByPath {
"/": {
id: "/";
path: "/";
fullPath: "/";
preLoaderRoute: typeof IndexImport;
parentRoute: typeof rootRoute;
};
}
}

// Create and export the route tree

export interface FileRoutesByFullPath {
"/": typeof IndexRoute;
}

export interface FileRoutesByTo {
"/": typeof IndexRoute;
}

export interface FileRoutesById {
__root__: typeof rootRoute;
"/": typeof IndexRoute;
}

export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath;
fullPaths: "/";
fileRoutesByTo: FileRoutesByTo;
to: "/";
id: "__root__" | "/";
fileRoutesById: FileRoutesById;
}

export interface RootRouteChildren {
IndexRoute: typeof IndexRoute;
}

const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
};

export const routeTree = rootRoute
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>();

/* prettier-ignore-end */

/* ROUTE_MANIFEST_START
{
"routes": {
"__root__": {
"filePath": "__root.tsx",
"children": [
"/"
]
},
"/": {
"filePath": "index.tsx"
}
}
}
ROUTE_MANIFEST_END */
17 changes: 17 additions & 0 deletions examples/minimal-tanstack-start/app/router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// app/router.tsx
import { createRouter as createTanStackRouter } from "@tanstack/react-router";
import { routeTree } from "./routeTree.gen";

export function createRouter() {
const router = createTanStackRouter({
routeTree,
});

return router;
}

declare module "@tanstack/react-router" {
interface Register {
router: ReturnType<typeof createRouter>;
}
}
38 changes: 38 additions & 0 deletions examples/minimal-tanstack-start/app/routes/__root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as React from "react";
import {
createRootRoute,
Outlet,
ScrollRestoration,
} from "@tanstack/react-router";
import { Body, Head, Html, Meta, Scripts } from "@tanstack/start";

// @ts-expect-error
import uploadthingCss from "@uploadthing/react/styles.css?url";

export const Route = createRootRoute({
component: RootComponent,
links: () => [{ rel: "stylesheet", href: uploadthingCss }],
});

function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
);
}

function RootDocument({ children }: { children: React.ReactNode }) {
return (
<Html>
<Head>
<Meta />
</Head>
<Body>
{children}
<ScrollRestoration />
<Scripts />
</Body>
</Html>
);
}
11 changes: 11 additions & 0 deletions examples/minimal-tanstack-start/app/routes/api/uploadthing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createAPIFileRoute } from "@tanstack/start/api";

import { createRouteHandler } from "uploadthing/server";

import { uploadRouter } from "../../server/uploadthing";

const handlers = createRouteHandler({ router: uploadRouter });
export const Route = createAPIFileRoute("/api/uploadthing")({
GET: handlers,
POST: handlers,
});
81 changes: 81 additions & 0 deletions examples/minimal-tanstack-start/app/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { createFileRoute } from "@tanstack/react-router";

import {
UploadButton,
UploadDropzone,
useUploadThing,
} from "../utils/uploadthing";


export const Route = createFileRoute("/")({
component: Home,
});


function Home() {
const { startUpload } = useUploadThing("videoAndImage", {
/**
* @see https://docs.uploadthing.com/api-reference/react#useuploadthing
*/
onBeforeUploadBegin: (files) => {
console.log("Uploading", files.length, "files");
return files;
},
onUploadBegin: (name) => {
console.log("Beginning upload of", name);
},
onClientUploadComplete: (res) => {
console.log("Upload Completed.", res.length, "files uploaded");
},
onUploadProgress(p) {
console.log("onUploadProgress", p);
},
});

return (
<main>
<UploadButton
/**
* @see https://docs.uploadthing.com/api-reference/react#uploadbutton
*/
endpoint="videoAndImage"
onClientUploadComplete={(res) => {
console.log(`onClientUploadComplete`, res);
alert("Upload Completed");
}}
onUploadBegin={() => {
console.log("upload begin");
}}
config={{ appendOnPaste: true, mode: "manual" }}
/>
<UploadDropzone
/**
* @see https://docs.uploadthing.com/api-reference/react#uploaddropzone
*/
endpoint="videoAndImage"
onUploadAborted={() => {
alert("Upload Aborted");
}}
onClientUploadComplete={(res) => {
console.log(`onClientUploadComplete`, res);
alert("Upload Completed");
}}
onUploadBegin={() => {
console.log("upload begin");
}}
/>
<input
type="file"
multiple
onChange={async (e) => {
const files = Array.from(e.target.files ?? []);

// Do something with files

// Then start the upload
await startUpload(files);
}}
/>
</main>
);
}
61 changes: 61 additions & 0 deletions examples/minimal-tanstack-start/app/server/uploadthing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createUploadthing, UTFiles } from "uploadthing/next";
import type { FileRouter } from "uploadthing/next";

const f = createUploadthing({
/**
* Log out more information about the error, but don't return it to the client
* @see https://docs.uploadthing.com/errors#error-formatting
*/
errorFormatter: (err) => {
console.log("Error uploading file", err.message);
console.log(" - Above error caused by:", err.cause);

return { message: err.message };
},
});

/**
* This is your Uploadthing file router. For more information:
* @see https://docs.uploadthing.com/api-reference/server#file-routes
*/
export const uploadRouter = {
videoAndImage: f({
image: {
maxFileSize: "32MB",
maxFileCount: 4,
acl: "public-read",
},
video: {
maxFileSize: "16MB",
},
blob: {
maxFileSize: "8GB",
},
})
.middleware(({ req, files }) => {
// Check some condition based on the incoming requrest
console.log("Request", req);
//^?
// if (!req.headers.get("x-some-header")) {
// throw new Error("x-some-header is required");
// }

// (Optional) Label your files with a custom identifier
const filesWithMyIds = files.map((file, idx) => ({
...file,
customId: `${idx}-HELLO`,
}));

// Return some metadata to be stored with the file
return { foo: "bar" as const, [UTFiles]: filesWithMyIds };
})
.onUploadComplete(({ file, metadata }) => {
metadata;
// ^?
file.customId;
// ^?
console.log("upload completed", file);
}),
} satisfies FileRouter;

export type OurFileRouter = typeof uploadRouter;
13 changes: 13 additions & 0 deletions examples/minimal-tanstack-start/app/ssr.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// app/ssr.tsx
import {
createStartHandler,
defaultStreamHandler,
} from "@tanstack/start/server";
import { getRouterManifest } from "@tanstack/start/router-manifest";

import { createRouter } from "./router";

export default createStartHandler({
createRouter,
getRouterManifest,
})(defaultStreamHandler);
12 changes: 12 additions & 0 deletions examples/minimal-tanstack-start/app/utils/uploadthing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {
generateReactHelpers,
generateUploadButton,
generateUploadDropzone,
} from "@uploadthing/react";

import type { OurFileRouter } from "../server/uploadthing";

export const UploadButton = generateUploadButton<OurFileRouter>();
export const UploadDropzone = generateUploadDropzone<OurFileRouter>();

export const { useUploadThing } = generateReactHelpers<OurFileRouter>();
25 changes: 25 additions & 0 deletions examples/minimal-tanstack-start/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@example/minimal-tanstack-start",
"private": true,
"type": "module",
"scripts": {
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start"
},
"dependencies": {
"@tanstack/react-router": "^1.58.7",
"@tanstack/start": "^1.58.7",
"@uploadthing/react": "7.0.2",
"@vitejs/plugin-react": "^4.3.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"uploadthing": "7.0.2",
"vinxi": "^0.4.3"
},
"devDependencies": {
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"typescript": "^5.5.2"
}
}
9 changes: 9 additions & 0 deletions examples/minimal-tanstack-start/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"moduleResolution": "Bundler",
"module": "ESNext",
"target": "ES2022",
"skipLibCheck": true
}
}
Loading

0 comments on commit ce3cf96

Please sign in to comment.