Compare commits

..

No commits in common. "cd8a8d746d21b26d54dfbb6fd1e62dc320b7e353" and "b1823f52943e6bdacfbc53499ca116376ee89f3e" have entirely different histories.

17 changed files with 136 additions and 5206 deletions

View File

@ -1,9 +0,0 @@
import type { CapacitorConfig } from "@capacitor/cli";
const config: CapacitorConfig = {
appId: "bettersplit.shrt.solutions",
appName: "bettersplit",
webDir: "out",
};
export default config;

View File

@ -3,16 +3,8 @@
* for Docker builds. * for Docker builds.
*/ */
import "./src/env.js"; import "./src/env.js";
import pwa from "next-pwa";
import { env } from "./src/env.js";
const withPWA = pwa({ /** @type {import("next").NextConfig} */
dest: "public", const config = {};
disable: env.NODE_ENV === "development",
register: true, // register the PWA service worker
skipWaiting: true,
});
export default withPWA({ export default config;
eslint: { ignoreDuringBuilds: true },
});

View File

@ -1,81 +1,75 @@
{ {
"name": "betterwise", "name": "betterwise",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "next build", "build": "next build",
"export": "next export", "check": "biome check .",
"check": "biome check .", "check:unsafe": "biome check --write --unsafe .",
"check:unsafe": "biome check --write --unsafe .", "check:write": "biome check --write .",
"check:write": "biome check --write .", "db:generate": "drizzle-kit generate",
"db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate",
"db:migrate": "drizzle-kit migrate", "db:push": "drizzle-kit push",
"db:push": "drizzle-kit push", "db:studio": "drizzle-kit studio",
"db:studio": "drizzle-kit studio", "dev": "next dev --turbo",
"dev": "next dev --turbo", "preview": "next build && next start",
"preview": "next build && next start", "start": "next start",
"start": "next start", "typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit", },
"android": "pnpm build && pnpm export && pnpm dlx cap sync android && pnpm dlx cap open android" "dependencies": {
}, "@auth/drizzle-adapter": "^1.7.2",
"dependencies": { "@hookform/resolvers": "^5.0.1",
"@auth/drizzle-adapter": "^1.7.2", "@paralleldrive/cuid2": "^2.2.2",
"@capacitor/cli": "^7.2.0", "@radix-ui/react-avatar": "^1.1.3",
"@capacitor/core": "^7.2.0", "@radix-ui/react-dialog": "^1.1.6",
"@hookform/resolvers": "^5.0.1", "@radix-ui/react-dropdown-menu": "^2.1.6",
"@paralleldrive/cuid2": "^2.2.2", "@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-avatar": "^1.1.3", "@radix-ui/react-popover": "^1.1.6",
"@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-select": "^2.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.6", "@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-label": "^2.1.2", "@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-popover": "^1.1.6", "@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-select": "^2.1.6", "@t3-oss/env-nextjs": "^0.12.0",
"@radix-ui/react-separator": "^1.1.2", "@tanstack/react-query": "^5.69.0",
"@radix-ui/react-slot": "^1.1.2", "@trpc/client": "^11.0.0",
"@radix-ui/react-tabs": "^1.1.3", "@trpc/react-query": "^11.0.0",
"@t3-oss/env-nextjs": "^0.12.0", "@trpc/server": "^11.0.0",
"@tanstack/react-query": "^5.69.0", "class-variance-authority": "^0.7.1",
"@trpc/client": "^11.0.0", "clsx": "^2.1.1",
"@trpc/react-query": "^11.0.0", "cmdk": "^1.1.1",
"@trpc/server": "^11.0.0", "drizzle-orm": "^0.41.0",
"@types/next-pwa": "^5.6.9", "lucide-react": "^0.487.0",
"class-variance-authority": "^0.7.1", "next": "^15.2.3",
"clsx": "^2.1.1", "next-auth": "5.0.0-beta.25",
"cmdk": "^1.1.1", "next-themes": "^0.4.6",
"drizzle-orm": "^0.41.0", "postgres": "^3.4.4",
"lucide-react": "^0.487.0", "react": "^19.0.0",
"next": "^15.2.3", "react-dom": "^19.0.0",
"next-auth": "5.0.0-beta.25", "react-hook-form": "^7.55.0",
"next-pwa": "^5.6.0", "server-only": "^0.0.1",
"next-themes": "^0.4.6", "sonner": "^2.0.3",
"postgres": "^3.4.4", "superjson": "^2.2.1",
"react": "^19.0.0", "tailwind-merge": "^3.1.0",
"react-dom": "^19.0.0", "tw-animate-css": "^1.2.5",
"react-hook-form": "^7.55.0", "use-debounce": "^10.0.4",
"server-only": "^0.0.1", "vaul": "^1.1.2",
"sonner": "^2.0.3", "zod": "^3.24.2",
"superjson": "^2.2.1", "zustand": "^5.0.3"
"tailwind-merge": "^3.1.0", },
"tw-animate-css": "^1.2.5", "devDependencies": {
"use-debounce": "^10.0.4", "@biomejs/biome": "1.9.4",
"vaul": "^1.1.2", "@tailwindcss/postcss": "^4.0.15",
"zod": "^3.24.2", "@types/node": "^20.14.10",
"zustand": "^5.0.3" "@types/react": "^19.0.0",
}, "@types/react-dom": "^19.0.0",
"devDependencies": { "drizzle-kit": "^0.30.5",
"@biomejs/biome": "1.9.4", "postcss": "^8.5.3",
"@tailwindcss/postcss": "^4.0.15", "tailwindcss": "^4.0.15",
"@types/node": "^20.14.10", "typescript": "^5.8.2"
"@types/react": "^19.0.0", },
"@types/react-dom": "^19.0.0", "ct3aMetadata": {
"drizzle-kit": "^0.30.5", "initVersion": "7.39.2"
"postcss": "^8.5.3", },
"tailwindcss": "^4.0.15", "packageManager": "pnpm@10.3.0"
"typescript": "^5.8.2"
},
"ct3aMetadata": {
"initVersion": "7.39.2"
},
"packageManager": "pnpm@10.3.0"
} }

4946
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@ type AppConfig = {
}; };
export const appConfig: AppConfig = { export const appConfig: AppConfig = {
name: "Bettesplit", name: "Betterwise",
navigator: [ navigator: [
{ {
name: "Home", name: "Home",

View File

@ -1,13 +1,11 @@
import AddFriendDrawer from "@/app/_components/friend/add-friend-drawer"; import AddFriendDrawer from "@/app/_components/friend/add-friend-drawer";
import FriendList from "@/app/_components/friend/friend-list"; import FriendList from "@/app/_components/friend/friend-list";
import Header from "@/components/header"; import Header from "@/components/header";
import { auth } from "@/server/auth";
import { api, HydrateClient } from "@/trpc/server"; import { api, HydrateClient } from "@/trpc/server";
import React from "react"; import React from "react";
export default async function Page() { export default async function Page() {
const session = await auth(); void api.friend.getAll.prefetch();
if (session?.user) void api.friend.getAll.prefetch();
return ( return (
<HydrateClient> <HydrateClient>

View File

@ -4,14 +4,13 @@ import React from "react";
export default function FriendRequestButton({}: {}) { export default function FriendRequestButton({}: {}) {
return ( return (
<div> <div>
{/* <Button <Button
variant={requestedBy === "me" ? "destructive" : "outline"} variant={requestedBy === "me" ? "destructive" : "outline"}
className="ml-auto" className="ml-auto"
size="sm" size="sm"
> >
{requestedBy === "me" ? "Cancel" : "Accept"} {requestedBy === "me" ? "Cancel" : "Accept"}
</Button> */} </Button>
friendRequestButton
</div> </div>
); );
} }

View File

@ -1,86 +0,0 @@
// "use client";
// import React, { useEffect, useState } from "react";
// export function usePwaInstallStatus() {
// const [isStandalone, setIsStandalone] = useState(false);
// const [isIOS, setIsIOS] = useState(false);
// const [isAndroid, setIsAndroid] = useState(false);
// useEffect(() => {
// const userAgent =
// navigator.userAgent || navigator.vendor || (window as any).opera;
// // iOS detection
// const iOS = /iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream;
// setIsIOS(iOS);
// // Android detection
// const android = /android/i.test(userAgent);
// setIsAndroid(android);
// // PWA "standalone" mode detection (works for both iOS & Android)
// const isInStandaloneMode =
// window.matchMedia("(display-mode: standalone)").matches ||
// (navigator as any).standalone === true; // for iOS Safari
// setIsStandalone(isInStandaloneMode);
// }, []);
// return { isIOS, isAndroid, isStandalone };
// }
// function InstallPrompt() {
// const { isIOS, isAndroid, isStandalone } = usePwaInstallStatus();
// const [deferredPrompt, setDeferredPrompt] = useState<any>(null);
// useEffect(() => {
// const handler = (e: any) => {
// e.preventDefault();
// setDeferredPrompt(e);
// };
// window.addEventListener("beforeinstallprompt", handler);
// return () => {
// window.removeEventListener("beforeinstallprompt", handler);
// };
// }, []);
// const handleInstallClick = () => {
// console.log("install clicked");
// if (deferredPrompt) {
// deferredPrompt.prompt();
// deferredPrompt.userChoice.then((choiceResult: any) => {
// if (choiceResult.outcome === "accepted") {
// console.log("User accepted the A2HS prompt");
// } else {
// console.log("User dismissed the A2HS prompt");
// }
// setDeferredPrompt(null);
// });
// }
// };
// if (isStandalone) {
// return null; // Already running as a PWA, no need to show install prompt
// }
// return (
// <div className="absolute w-full h-20 z-50 bg-red-500 left-0 flex items-center justify-center right-0 bottom-0 text-white">
// {isIOS && <p>Tap "Share" and "Add to Home Screen" to install the app.</p>}
// {isAndroid && <button onClick={handleInstallClick}>Install App</button>}
// </div>
// );
// }
// export default function PWAWrapper({
// children,
// }: {
// children: React.ReactNode;
// }) {
// return (
// <>
// <InstallPrompt />
// {children}
// </>
// );
// }

View File

@ -5,7 +5,6 @@ import { Geist } from "next/font/google";
import { Toaster } from "@/components/ui/sonner"; import { Toaster } from "@/components/ui/sonner";
import { TRPCReactProvider } from "@/trpc/react"; import { TRPCReactProvider } from "@/trpc/react";
import { ThemeProvider } from "@/components/theme-provider"; import { ThemeProvider } from "@/components/theme-provider";
// import PWAWrapper from "./_components/install-prompt";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Create T3 App", title: "Create T3 App",
@ -31,8 +30,6 @@ export default function RootLayout({
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
> >
{/* <PWAWrapper>
</PWAWrapper> */}
{children} {children}
<Toaster position="top-center" /> <Toaster position="top-center" />
</ThemeProvider> </ThemeProvider>

View File

@ -1,26 +0,0 @@
import { appConfig } from "@/app.config";
import type { MetadataRoute } from "next";
export default function manifest(): MetadataRoute.Manifest {
return {
name: appConfig.name,
short_name: "NextPWA",
description: "A Progressive Web App built with Next.js",
start_url: "/",
display: "standalone",
background_color: "#ffffff",
theme_color: "#000000",
icons: [
{
src: "/icon-192x192.png",
sizes: "192x192",
type: "image/png",
},
{
src: "/icon-512x512.png",
sizes: "512x512",
type: "image/png",
},
],
};
}

View File

@ -15,7 +15,7 @@ function NavLink({ href, name, icon }: NavLink) {
asChild asChild
variant={"ghost"} variant={"ghost"}
className={cn( className={cn(
"p-2 size-12 text-muted-foreground/75 flex flex-col gap-2 hover:bg-transparent dark:hover:bg-transparent ", "p-2 size-12 text-muted-foreground/75 flex flex-col gap-2 ",
active && "text-foreground " active && "text-foreground "
)} )}
> >

View File

@ -1,10 +1,10 @@
"use client"; "use client"
import { useTheme } from "next-themes"; import { useTheme } from "next-themes"
import { Toaster as Sonner, type ToasterProps } from "sonner"; import { Toaster as Sonner, ToasterProps } from "sonner"
const Toaster = ({ ...props }: ToasterProps) => { const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme(); const { theme = "system" } = useTheme()
return ( return (
<Sonner <Sonner
@ -19,7 +19,7 @@ const Toaster = ({ ...props }: ToasterProps) => {
} }
{...props} {...props}
/> />
); )
}; }
export { Toaster }; export { Toaster }

View File

@ -38,7 +38,6 @@ declare module "next-auth" {
* @see https://next-auth.js.org/configuration/options * @see https://next-auth.js.org/configuration/options
*/ */
export const authConfig = { export const authConfig = {
trustHost: true,
providers: [ providers: [
DiscordProvider, DiscordProvider,
/** /**

View File

@ -1,43 +1,43 @@
{ {
"compilerOptions": { "compilerOptions": {
/* Base Options: */ /* Base Options: */
"esModuleInterop": true, "esModuleInterop": true,
"skipLibCheck": true, "skipLibCheck": true,
"target": "es2022", "target": "es2022",
"allowJs": true, "allowJs": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"moduleDetection": "force", "moduleDetection": "force",
"isolatedModules": true, "isolatedModules": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
/* Strictness */ /* Strictness */
"strict": true, "strict": true,
"noUncheckedIndexedAccess": true, "noUncheckedIndexedAccess": true,
"checkJs": true, "checkJs": true,
/* Bundled projects */ /* Bundled projects */
"lib": ["dom", "dom.iterable", "ES2022"], "lib": ["dom", "dom.iterable", "ES2022"],
"noEmit": true, "noEmit": true,
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Bundler", "moduleResolution": "Bundler",
"jsx": "preserve", "jsx": "preserve",
"plugins": [{ "name": "next" }], "plugins": [{ "name": "next" }],
"incremental": true, "incremental": true,
/* Path Aliases */ /* Path Aliases */
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"]
} }
}, },
"include": [ "include": [
".eslintrc.cjs", ".eslintrc.cjs",
"next-env.d.ts", "next-env.d.ts",
"**/*.ts", "**/*.ts",
"**/*.tsx", "**/*.tsx",
"**/*.cjs", "**/*.cjs",
"**/*.js", "**/*.js",
".next/types/**/*.ts" ".next/types/**/*.ts"
], ],
"exclude": ["node_modules", "public/sw.js", "public/workbox-*.js"] "exclude": ["node_modules"]
} }