diff --git a/app/(auth)/cloud/page.tsx b/app/(auth)/cloud/page.tsx index 8f73b19..8c13393 100644 --- a/app/(auth)/cloud/page.tsx +++ b/app/(auth)/cloud/page.tsx @@ -3,6 +3,7 @@ import { Card, CardContent, CardTitle } from "@/components/ui/card" import { ColoredText } from "@/components/ui/colored-text" import config from "@/lib/config" import { PLANS } from "@/lib/stripe" +import { Mail } from "lucide-react" import Link from "next/link" import { redirect } from "next/navigation" @@ -15,7 +16,8 @@ export default async function ChoosePlanPage() {
- Choose your Cloud Edition plan + TaxHacker Cloud Edition +

Choose your plan

{config.auth.disableSignup ? ( @@ -23,17 +25,39 @@ export default async function ChoosePlanPage() { Creating new account is disabled for now. Please use the self-hosted version.
) : ( -
- {Object.values(PLANS) - .filter((plan) => plan.isAvailable) - .map((plan) => ( - - ))} +
+
+ {Object.values(PLANS) + .filter((plan) => plan.isAvailable) + .map((plan) => ( + + ))} +
+ +
+ By signing up, you agree to our{" "} + + Terms of Service + + ,{" "} + + Privacy Policy + + , and{" "} + + AI Usage Disclosure + +
)} +
- + + Contact us for custom plans
diff --git a/app/docs/ai/page.tsx b/app/docs/ai/page.tsx index 92112b2..db3f89e 100644 --- a/app/docs/ai/page.tsx +++ b/app/docs/ai/page.tsx @@ -45,7 +45,7 @@ export default async function AI() {

diff --git a/app/landing/landing.tsx b/app/landing/landing.tsx index 3b1c9a3..bb34ec1 100644 --- a/app/landing/landing.tsx +++ b/app/landing/landing.tsx @@ -15,10 +15,16 @@ export default function LandingPage() {

+ Log In + + - Get Started + Sign Up
@@ -35,7 +41,7 @@ export default function LandingPage() { Let AI finally care about your taxes, scan your receipts and analyze your expenses

- A self-hosted accounting app crafted with love for freelancers and small businesses. + A self-hosted accounting app crafted with love for freelancers and small businesses

-
- {/* Self-Hosted Version */} -
-
- Use Your Own Server -
-

- Self-Hosted Edition -

- - - Github + Docker Compose - -
- +
{/* Cloud Version */}
@@ -302,12 +273,47 @@ export default function LandingPage() { Automatic updates and new features - + LET'S GO! + +
+ + {/* Self-Hosted Version */} +
+
+ Use Your Own Server +
+

+ Self-Hosted Edition +

+
    +
  • + + Free and open source +
  • +
  • + + Complete control over your data +
  • +
  • + + Use at your own infrastructure +
  • +
  • + + Bring your own OpenAI keys +
  • +
+ + Github + Docker Compose +
@@ -431,7 +437,7 @@ export default function LandingPage() {
Made with ❤️ in Berlin by{" "} - vas3k + @vas3k
@@ -453,6 +459,13 @@ export default function LandingPage() { Cookie Policy + + Source Code +
diff --git a/components/auth/signup-form.tsx b/components/auth/signup-form.tsx deleted file mode 100644 index 2707700..0000000 --- a/components/auth/signup-form.tsx +++ /dev/null @@ -1,96 +0,0 @@ -"use client" - -import { FormInput } from "@/components/forms/simple" -import { Button } from "@/components/ui/button" -import { authClient } from "@/lib/auth-client" -import { useRouter } from "next/navigation" -import { useState } from "react" - -export default function SignupForm() { - const [name, setName] = useState("") - const [email, setEmail] = useState("") - const [otp, setOtp] = useState("") - const [isOtpSent, setIsOtpSent] = useState(false) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(null) - const router = useRouter() - - const handleSendOtp = async (e: React.FormEvent) => { - e.preventDefault() - setIsLoading(true) - setError(null) - - try { - await authClient.emailOtp.sendVerificationOtp({ - email, - type: "sign-in", - }) - setIsOtpSent(true) - } catch (err) { - setError(err instanceof Error ? err.message : "Failed to send OTP") - } finally { - setIsLoading(false) - } - } - - const handleVerifyOtp = async (e: React.FormEvent) => { - e.preventDefault() - setIsLoading(true) - setError(null) - - try { - await authClient.signIn.emailOtp({ - email, - otp, - }) - await authClient.updateUser({ - name, - }) - router.push("/dashboard") - } catch (err) { - setError(err instanceof Error ? err.message : "Failed to verify OTP") - } finally { - setIsLoading(false) - } - } - - return ( -
- setName(e.target.value)} - required - disabled={isOtpSent} - /> - - setEmail(e.target.value)} - required - disabled={isOtpSent} - /> - - {isOtpSent && ( - setOtp(e.target.value)} - required - maxLength={6} - pattern="[0-9]{6}" - /> - )} - - {error &&

{error}

} - - - - ) -} diff --git a/components/dashboard/welcome-widget.tsx b/components/dashboard/welcome-widget.tsx index b351f09..34dbd41 100644 --- a/components/dashboard/welcome-widget.tsx +++ b/components/dashboard/welcome-widget.tsx @@ -34,8 +34,8 @@ export async function WelcomeWidget() {

- I'm a little accountant app that tries to help you deal with endless receipts, checks and invoices with - (you guessed it) GenAI. Here's what I can do: + I'm a little accountant app that helps you deal with endless receipts, checks and invoices with (you + guessed it) AI. Here's what I can do:

  • @@ -50,7 +50,7 @@ export async function WelcomeWidget() {
  • All LLM prompts are configurable: for fields, categories and projects. You can go to - settings and change them. + settings and change them however you want.
  • I save data in a local SQLite database and can export it to CSV and ZIP archives. diff --git a/components/sidebar/sidebar-user.tsx b/components/sidebar/sidebar-user.tsx index 4c88957..1dd1897 100644 --- a/components/sidebar/sidebar-user.tsx +++ b/components/sidebar/sidebar-user.tsx @@ -51,16 +51,9 @@ export default function SidebarUser({ profile, isSelfHosted }: { profile: UserPr - Profile Settings + Profile & Plan - {/* - - - Your Subscription - - */} - diff --git a/lib/stripe.ts b/lib/stripe.ts index d281eb3..e981160 100644 --- a/lib/stripe.ts +++ b/lib/stripe.ts @@ -38,15 +38,16 @@ export const PLANS: Record = { early: { code: "early", name: "Early Adopter", - description: "Special plan for our early users", + description: "Discounted plan for our first users who can forgive us bugs and childish problems :)", benefits: [ + "Special price for early adopters", "512 Mb of storage", "1000 AI file analysis", "Unlimited transactions", "Unlimited fields, categories and projects", ], - price: "€50/year", - stripePriceId: "price_1RGzKUPKOUEUzVB3hVyo2n57", + price: "€35 for a year", + stripePriceId: "price_1RHTmTAs8DS4NhOzGnWqxvZC", limits: { storage: 512 * 1024 * 1024, ai: 1000,