Feature/UI: updated buttons, cards, navigation, logo
This commit is contained in:
parent
62e2255b5e
commit
0b9902dc5c
@ -1,56 +1,23 @@
|
|||||||
import * as React from "react";
|
import React from 'react'
|
||||||
import { Slot } from "@radix-ui/react-slot";
|
|
||||||
import { cva, type VariantProps } from "class-variance-authority";
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
variant?: 'primary' | 'secondary'
|
||||||
const buttonVariants = cva(
|
children: React.ReactNode
|
||||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
||||||
{
|
|
||||||
variants: {
|
|
||||||
variant: {
|
|
||||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
||||||
destructive:
|
|
||||||
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
||||||
outline:
|
|
||||||
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
||||||
secondary:
|
|
||||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
||||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
||||||
link: "text-primary underline-offset-4 hover:underline",
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
default: "h-10 px-4 py-2",
|
|
||||||
sm: "h-9 rounded-md px-3",
|
|
||||||
lg: "h-11 rounded-md px-8",
|
|
||||||
icon: "h-10 w-10",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
defaultVariants: {
|
|
||||||
variant: "default",
|
|
||||||
size: "default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export interface ButtonProps
|
|
||||||
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
||||||
VariantProps<typeof buttonVariants> {
|
|
||||||
asChild?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
export function Button({ variant = 'primary', children, className = '', ...props }: ButtonProps) {
|
||||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
const baseClasses = 'px-4 py-2 rounded-md font-medium transition-colors'
|
||||||
const Comp = asChild ? Slot : "button";
|
const variantClasses = {
|
||||||
return (
|
primary: 'bg-blue-600 text-white hover:bg-blue-700',
|
||||||
<Comp
|
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
|
||||||
className={cn(buttonVariants({ variant, size, className }))}
|
}
|
||||||
ref={ref}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
Button.displayName = "Button";
|
|
||||||
|
|
||||||
export { Button, buttonVariants };
|
return (
|
||||||
|
<button
|
||||||
|
className={`${baseClasses} ${variantClasses[variant]} ${className}`}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,76 +1,30 @@
|
|||||||
import * as React from "react"
|
import React from 'react'
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
interface CardProps {
|
||||||
|
children: React.ReactNode
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
const Card = React.forwardRef<
|
export function Card({ children, className = '' }: CardProps) {
|
||||||
HTMLDivElement,
|
return (
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
<div className={`bg-white rounded-lg shadow-md p-6 ${className}`}>
|
||||||
>(({ className, ...props }, ref) => (
|
{children}
|
||||||
<div
|
</div>
|
||||||
ref={ref}
|
)
|
||||||
className={cn(
|
}
|
||||||
"rounded-xl border bg-card text-card-foreground shadow",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
Card.displayName = "Card"
|
|
||||||
|
|
||||||
const CardHeader = React.forwardRef<
|
export function CardHeader({ children, className = '' }: CardProps) {
|
||||||
HTMLDivElement,
|
return (
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
<div className={`mb-4 ${className}`}>
|
||||||
>(({ className, ...props }, ref) => (
|
{children}
|
||||||
<div
|
</div>
|
||||||
ref={ref}
|
)
|
||||||
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
}
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
CardHeader.displayName = "CardHeader"
|
|
||||||
|
|
||||||
const CardTitle = React.forwardRef<
|
export function CardContent({ children, className = '' }: CardProps) {
|
||||||
HTMLParagraphElement,
|
return (
|
||||||
React.HTMLAttributes<HTMLHeadingElement>
|
<div className={className}>
|
||||||
>(({ className, ...props }, ref) => (
|
{children}
|
||||||
<h3
|
</div>
|
||||||
ref={ref}
|
)
|
||||||
className={cn("font-semibold leading-none tracking-tight", className)}
|
}
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
CardTitle.displayName = "CardTitle"
|
|
||||||
|
|
||||||
const CardDescription = React.forwardRef<
|
|
||||||
HTMLParagraphElement,
|
|
||||||
React.HTMLAttributes<HTMLParagraphElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<p
|
|
||||||
ref={ref}
|
|
||||||
className={cn("text-sm text-muted-foreground", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
CardDescription.displayName = "CardDescription"
|
|
||||||
|
|
||||||
const CardContent = React.forwardRef<
|
|
||||||
HTMLDivElement,
|
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
||||||
))
|
|
||||||
CardContent.displayName = "CardContent"
|
|
||||||
|
|
||||||
const CardFooter = React.forwardRef<
|
|
||||||
HTMLDivElement,
|
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<div
|
|
||||||
ref={ref}
|
|
||||||
className={cn("flex items-center p-6 pt-0", className)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
CardFooter.displayName = "CardFooter"
|
|
||||||
|
|
||||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
|
||||||
183
docs/readme.md
183
docs/readme.md
@ -1,15 +1,174 @@
|
|||||||
## fitai
|
# FitAI
|
||||||
|
|
||||||
# description
|
Integrated AI solution for fitness houses and their clients with Clerk authentication.
|
||||||
|
|
||||||
- fitai is integrated ai solution for fitness houses and their clients,
|
## Project Structure
|
||||||
its allow to easy menagment of clients, tracking of payments, usage of resourcess,
|
|
||||||
attendance, habits etc.
|
|
||||||
these will be phase one:
|
|
||||||
solution is composed of a admin app, where we are doing managment tasks, we visualize and
|
|
||||||
expose importatnt data to menagment and trainers, and a expo/reactnative mobile app for users.
|
|
||||||
via app we will be tracking attendance and payments, we will be sending notification etc.
|
|
||||||
|
|
||||||
# phase 2
|
```
|
||||||
we will be tracking user inputs via manual input and devices, backend will analyze data and propose
|
fitai/
|
||||||
excercises etc.
|
├── apps/
|
||||||
|
│ ├── admin/ # Next.js admin dashboard
|
||||||
|
│ └── mobile/ # React Native mobile app (Expo)
|
||||||
|
├── packages/
|
||||||
|
│ └── shared/ # Shared types and utilities
|
||||||
|
└── AGENTS.md # Development guidelines
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Node.js >= 18.0.0
|
||||||
|
- npm >= 9.0.0
|
||||||
|
- Clerk account (sign up at https://clerk.com)
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
```bash
|
||||||
|
# Install root dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Install admin dependencies
|
||||||
|
cd apps/admin && npm install
|
||||||
|
|
||||||
|
# Install mobile dependencies
|
||||||
|
cd apps/mobile && npm install --legacy-peer-deps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authentication Setup
|
||||||
|
|
||||||
|
FitAI uses Clerk for authentication. Follow these steps:
|
||||||
|
|
||||||
|
1. **Create a Clerk account** at https://dashboard.clerk.com
|
||||||
|
2. **Create a new application** in the Clerk dashboard
|
||||||
|
3. **Copy your API keys** (Publishable Key and Secret Key)
|
||||||
|
4. **Configure environment variables**:
|
||||||
|
|
||||||
|
**Admin App** (`apps/admin/.env.local`):
|
||||||
|
```env
|
||||||
|
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_your_key_here
|
||||||
|
CLERK_SECRET_KEY=sk_test_your_key_here
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mobile App** (`apps/mobile/.env`):
|
||||||
|
```env
|
||||||
|
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_your_key_here
|
||||||
|
```
|
||||||
|
|
||||||
|
📖 **See [CLERK_SETUP.md](./CLERK_SETUP.md) for detailed setup instructions**
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
**Important**: Set up environment variables before running the apps!
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Admin dashboard (http://localhost:3000)
|
||||||
|
cd apps/admin && npm run dev
|
||||||
|
|
||||||
|
# Mobile app (http://localhost:8081) - Requires Expo SDK 54
|
||||||
|
cd apps/mobile && npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
**First-time setup checklist**:
|
||||||
|
- [ ] Create Clerk account and application
|
||||||
|
- [ ] Add API keys to `.env.local` (admin) and `.env` (mobile)
|
||||||
|
- [ ] Verify both apps start without errors
|
||||||
|
- [ ] Test sign-up and sign-in flows
|
||||||
|
|
||||||
|
### Mobile App Setup
|
||||||
|
- **Expo SDK**: 50 (stable, compatible with Expo Go)
|
||||||
|
- **Assets**: Placeholder icons and splash screen included
|
||||||
|
- **Navigation**: Expo Router with tab-based layout
|
||||||
|
- **Authentication**: Secure storage with expo-secure-store
|
||||||
|
- **Babel**: babel-preset-expo for proper transpilation
|
||||||
|
|
||||||
|
### Known Compatibility Notes
|
||||||
|
- Use Expo Go with SDK 50 for mobile testing
|
||||||
|
- For SDK 54, upgrade all dependencies to latest versions
|
||||||
|
- Current setup prioritizes stability over latest features
|
||||||
|
|
||||||
|
### Build & Test
|
||||||
|
```bash
|
||||||
|
# Build all apps
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Lint code
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
# Type checking
|
||||||
|
npm run typecheck
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Authentication (Clerk)
|
||||||
|
- 🔐 Secure email/password authentication
|
||||||
|
- ✉️ Email verification
|
||||||
|
- 🔄 Session management
|
||||||
|
- 🎨 Customizable UI components
|
||||||
|
- 📱 Multi-platform support (Web + Mobile)
|
||||||
|
- 🛡️ Built-in security features
|
||||||
|
|
||||||
|
### Admin Dashboard
|
||||||
|
- 👥 User management (CRUD operations)
|
||||||
|
- 📊 Analytics dashboard with charts
|
||||||
|
- 🎯 Role-based access control
|
||||||
|
- 📈 Data visualization with AG Grid
|
||||||
|
- 💳 Payment tracking (coming soon)
|
||||||
|
- 📅 Attendance monitoring (coming soon)
|
||||||
|
|
||||||
|
### Mobile App
|
||||||
|
- 🔐 Secure sign-in/sign-up
|
||||||
|
- 👤 User profile management
|
||||||
|
- 📱 Native mobile experience
|
||||||
|
- 🔔 Push notifications ready
|
||||||
|
- ✅ Attendance check-in (coming soon)
|
||||||
|
- 💰 Payment history (coming soon)
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
- **Clerk**: Complete authentication and user management platform
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- **Admin**: Next.js 14 (App Router), React 19, TypeScript, Tailwind CSS
|
||||||
|
- **Mobile**: React Native, Expo SDK 54, Expo Router, TypeScript
|
||||||
|
|
||||||
|
### Backend & Database
|
||||||
|
- **Database**: SQLite with Drizzle ORM
|
||||||
|
- **API**: Next.js API Routes (REST)
|
||||||
|
|
||||||
|
### Development Tools
|
||||||
|
- **State Management**: React Query, React Hook Form
|
||||||
|
- **Validation**: Zod schemas
|
||||||
|
- **Data Grid**: AG Grid for advanced user management
|
||||||
|
- **Charts**: AG Charts for analytics and visualization
|
||||||
|
- **Testing**: Jest, Testing Library (configured)
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
fitai/
|
||||||
|
├── apps/
|
||||||
|
│ ├── admin/ # Next.js admin dashboard
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── app/ # App Router pages & API routes
|
||||||
|
│ │ │ ├── components/
|
||||||
|
│ │ │ └── lib/ # Database & utilities
|
||||||
|
│ │ └── .env.local # Admin environment variables
|
||||||
|
│ │
|
||||||
|
│ └── mobile/ # Expo React Native app
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── app/ # Expo Router screens
|
||||||
|
│ │ │ ├── (auth)/ # Authentication screens
|
||||||
|
│ │ │ └── (tabs)/ # Main app tabs
|
||||||
|
│ │ └── components/
|
||||||
|
│ └── .env # Mobile environment variables
|
||||||
|
│
|
||||||
|
├── packages/
|
||||||
|
│ ├── database/ # Drizzle ORM schemas & DB client
|
||||||
|
│ └── shared/ # Shared types & utilities
|
||||||
|
│
|
||||||
|
└── CLERK_SETUP.md # Detailed authentication setup guide
|
||||||
|
```
|
||||||
16
ter
Normal file
16
ter
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS
|
||||||
|
|
||||||
|
Commands marked with * may be preceded by a number, _N.
|
||||||
|
Notes in parentheses indicate the behavior if _N is given.
|
||||||
|
A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
|
||||||
|
|
||||||
|
h H Display this help.
|
||||||
|
q :q Q :Q ZZ Exit.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
MMOOVVIINNGG
|
||||||
|
|
||||||
|
e ^E j ^N CR * Forward one line (or _N lines).
|
||||||
|
y ^Y k ^K ^P * Backward one line (or _N lines).
|
||||||
|
f ^F ^V SPACE * Forward one window (or _N lines).
|
||||||
Loading…
Reference in New Issue
Block a user