├── .prettierignore ├── app ├── db │ ├── schema │ │ ├── index.ts │ │ ├── post.ts │ │ └── auth.ts │ ├── seed.ts │ └── client.ts ├── images │ └── og.png ├── api.ts ├── client.tsx ├── ssr.tsx ├── lib │ ├── utils.ts │ ├── seo.ts │ └── cache.ts ├── components │ ├── ui │ │ ├── label.tsx │ │ ├── textarea.tsx │ │ ├── input.tsx │ │ ├── sonner.tsx │ │ ├── avatar.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ └── form.tsx │ ├── not-found.tsx │ └── default-catch-boundary.tsx ├── router.tsx ├── actions │ ├── auth.ts │ └── post.ts ├── routeTree.gen.ts ├── styles │ └── globals.css ├── env.ts ├── hooks │ ├── post.ts │ └── useMutation.ts ├── routes │ ├── __root.tsx │ ├── api │ │ └── auth │ │ │ └── callback.github.ts │ └── index.tsx ├── auth │ └── index.ts └── trpc │ └── init.ts ├── app-screenshot.png ├── public ├── favicon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png └── site.webmanifest ├── .prettierrc ├── postcss.config.js ├── .eslintrc ├── app.config.ts ├── drizzle.config.ts ├── components.json ├── .env.example ├── tsconfig.json ├── .gitignore ├── LICENSE ├── tailwind.config.js ├── package.json └── README.md /.prettierignore: -------------------------------------------------------------------------------- 1 | **/build 2 | **/public 3 | pnpm-lock.yaml 4 | routeTree.gen.ts -------------------------------------------------------------------------------- /app/db/schema/index.ts: -------------------------------------------------------------------------------- 1 | export * from './post' 2 | export * from './auth' 3 | -------------------------------------------------------------------------------- /app/images/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/app/images/og.png -------------------------------------------------------------------------------- /app-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/app-screenshot.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": false, 4 | "trailingComma": "all" 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ally-ahmed/tss-app/HEAD/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["react-app"], 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["react-hooks"] 5 | } 6 | -------------------------------------------------------------------------------- /app/api.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createStartAPIHandler, 3 | defaultAPIFileRouteHandler, 4 | } from '@tanstack/start/api' 5 | 6 | export default createStartAPIHandler(defaultAPIFileRouteHandler) 7 | -------------------------------------------------------------------------------- /app/client.tsx: -------------------------------------------------------------------------------- 1 | import { StartClient } from '@tanstack/start' 2 | import { hydrateRoot } from 'react-dom/client' 3 | import { createRouter } from './router' 4 | 5 | const router = createRouter() 6 | 7 | hydrateRoot(document.getElementById('root')!, ) 8 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /app.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@tanstack/start/config' 2 | 3 | import tsConfigPaths from 'vite-tsconfig-paths' 4 | 5 | export default defineConfig({ 6 | vite: { 7 | plugins: () => [ 8 | tsConfigPaths({ 9 | projects: ['./tsconfig.json'], 10 | }), 11 | ], 12 | }, 13 | }) 14 | -------------------------------------------------------------------------------- /app/ssr.tsx: -------------------------------------------------------------------------------- 1 | import { getRouterManifest } from '@tanstack/start/router-manifest' 2 | import { 3 | createStartHandler, 4 | defaultStreamHandler, 5 | } from '@tanstack/start/server' 6 | 7 | import { createRouter } from './router' 8 | 9 | export default createStartHandler({ 10 | createRouter, 11 | getRouterManifest, 12 | })(defaultStreamHandler) 13 | -------------------------------------------------------------------------------- /drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'drizzle-kit' 2 | 3 | import { env } from '@/env' 4 | 5 | export default { 6 | schema: './app/db/schema/index.ts', 7 | out: './app/db/migrations', 8 | dialect: 'sqlite', 9 | driver: 'turso', 10 | dbCredentials: { 11 | url: env.DATABASE_URL, 12 | authToken: env.DATABASE_AUTH_TOKEN!, 13 | }, 14 | verbose: true, 15 | } satisfies Config 16 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "app/styles/globals.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /app/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from 'clsx' 2 | import { twMerge } from 'tailwind-merge' 3 | import { customAlphabet } from 'nanoid' 4 | 5 | export function cn(...inputs: ClassValue[]) { 6 | return twMerge(clsx(inputs)) 7 | } 8 | 9 | export function genId(pfx?: string) { 10 | const nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 10) 11 | // return [pfx, nanoid()].join("_"); 12 | return nanoid() 13 | } 14 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Since the ".env" file is gitignored, you can use the ".env.example" file to 2 | # build a new ".env" file when you clone the repo. Keep this file up-to-date 3 | # when you add new variables to `.env`. 4 | 5 | # This file will be committed to version control, so make sure not to have any 6 | # secrets in it. If you are cloning this repo, create a copy of this file named 7 | # ".env" and populate it with your secrets. 8 | 9 | # When adding additional environment variables, the schema in "/app/env.ts" 10 | # should be updated accordingly. 11 | 12 | # Drizzle 13 | DATABASE_URL="file:./db.sqlite" 14 | 15 | #OAuth 16 | GITHUB_CLIENT_ID="" 17 | GITHUB_CLIENT_SECRET="" -------------------------------------------------------------------------------- /app/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /app/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |