diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..8b69ea04 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,12 +1,13 @@ --- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' +name: Feature Request +about: Suggest a new feature or enhancement for ExpenseFlow +title: '[FEATURE] ' +labels: 'enhancement' assignees: '' - --- +## 🎯 Feature Overview + **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] @@ -16,5 +17,149 @@ A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. -**Additional context** -Add any other context or screenshots about the feature request here. +--- + +## πŸ“‹ Feature Details + +### User Story +As a [type of user], I want [goal] so that [benefit]. + +### Acceptance Criteria +- [ ] Criterion 1: [Description] +- [ ] Criterion 2: [Description] +- [ ] Criterion 3: [Description] + +### Expected Behavior +Describe the expected behavior when this feature is implemented. + +### Current Behavior +Describe what currently happens (if applicable). + +--- + +## 🎨 UI/UX Considerations + +### Mockups/Wireframes +If applicable, add mockups, wireframes, or screenshots to help explain your feature. + +### User Flow +Describe how users would interact with this feature: + +```mermaid +flowchart TD + A[User Action] --> B[Feature Trigger] + B --> C[Process] + C --> D[Result] + D --> E[User Feedback] + + style A fill:#64ffda,stroke:#0f0f23,stroke-width:2px + style D fill:#10ac84,stroke:#0f0f23,stroke-width:2px +``` + +--- + +## πŸ”§ Technical Considerations + +### Implementation Approach +Describe how this feature could be implemented technically. + +### Dependencies +- [ ] No new dependencies required +- [ ] Requires new library: [Library name] +- [ ] Requires backend changes +- [ ] Requires database changes + +### Performance Impact +- [ ] No performance impact expected +- [ ] Minimal performance impact +- [ ] May require optimization + +### Browser Compatibility +- [ ] Works on all modern browsers +- [ ] Requires specific browser features: [List features] +- [ ] May need polyfills + +--- + +## πŸ“Š Impact Assessment + +### User Impact +- **High**: This feature would significantly improve user experience +- **Medium**: This feature would be a nice addition +- **Low**: This feature is a minor enhancement + +### Priority +- [ ] πŸ”΄ Critical - Blocks other features +- [ ] 🟠 High - Important for user experience +- [ ] 🟑 Medium - Nice to have +- [ ] 🟒 Low - Can be added later + +### Complexity +- [ ] 🟒 Simple - Quick implementation +- [ ] 🟑 Medium - Moderate effort required +- [ ] 🟠 Complex - Significant development needed +- [ ] πŸ”΄ Very Complex - Major feature requiring architecture changes + +--- + +## πŸ§ͺ Testing Considerations + +### Test Cases +- [ ] Unit tests required +- [ ] Integration tests required +- [ ] Manual testing scenarios: [Describe] + +### Edge Cases +List any edge cases that should be considered: +- Edge case 1 +- Edge case 2 + +--- + +## πŸ“š Additional Context + +### Related Issues +Link to any related issues: +- Related issue #1 +- Related issue #2 + +### References +- [ ] Similar features in other apps: [Links] +- [ ] Design inspiration: [Links] +- [ ] Technical documentation: [Links] + +### Additional Information +Add any other context, screenshots, or examples about the feature request here. + +--- + +## βœ… Checklist + +Before submitting, please ensure: + +- [ ] I have searched existing issues to avoid duplicates +- [ ] I have provided a clear description of the feature +- [ ] I have considered the user experience +- [ ] I have thought about technical implementation +- [ ] I have included any relevant mockups or examples +- [ ] I have checked that this aligns with the project goals + +--- + +## 🀝 Contribution + +**Are you willing to work on this feature?** +- [ ] Yes, I'd like to implement this +- [ ] Maybe, with guidance +- [ ] No, but I can help with testing/feedback + +**Skills/Resources Needed:** +- [ ] Frontend development +- [ ] Backend development +- [ ] UI/UX design +- [ ] Testing +- [ ] Documentation + +--- + +**Thank you for taking the time to suggest this feature! πŸŽ‰** diff --git a/.gitignore b/.gitignore index 2dc21cb9..3e3f81ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,52 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs +dist/ +build/ +*.min.js +*.min.css + +# Environment variables +.env +.env.local +.env.*.local + +# IDE and Editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store +Thumbs.db + +# Logs +logs/ +*.log + +# OS files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Desktop.ini + +# Temporary files +*.tmp +*.temp +.cache/ + +# Service Worker cache (optional - uncomment if you don't want to track) +# sw-cache/ + +# Backup files +*.bak +*.backup .env .node_modules diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 00000000..e2ec7102 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,185 @@ +# πŸš€ Deployment Guide for ExpenseFlow + +This guide will help you deploy ExpenseFlow to GitHub Pages or any static hosting service. + +## πŸ“‹ Prerequisites + +- A GitHub account +- Git installed on your local machine +- The ExpenseFlow repository cloned locally + +## 🌐 GitHub Pages Deployment + +### Option 1: Deploy from Root Directory (Recommended) + +1. **Push your code to GitHub** + ```bash + git add . + git commit -m "Initial commit" + git push origin main + ``` + +2. **Enable GitHub Pages** + - Go to your repository on GitHub + - Click on **Settings** β†’ **Pages** + - Under **Source**, select **Deploy from a branch** + - Choose **main** branch and **/ (root)** folder + - Click **Save** + +3. **Access your site** + - Your site will be available at: `https://yourusername.github.io/ExpenseFlow/` + - Or if using a custom domain: `https://yourdomain.com` + +### Option 2: Deploy from `gh-pages` Branch + +1. **Create and switch to gh-pages branch** + ```bash + git checkout -b gh-pages + git push origin gh-pages + ``` + +2. **Enable GitHub Pages** + - Go to **Settings** β†’ **Pages** + - Select **gh-pages** branch and **/ (root)** folder + +## πŸ“ File Structure Requirements + +Ensure your repository has the following structure: + +``` +ExpenseFlow/ +β”œβ”€β”€ index.html # Main entry point +β”œβ”€β”€ expensetracker.css # Styles +β”œβ”€β”€ trackerscript.js # JavaScript logic +β”œβ”€β”€ manifest.json # PWA manifest +β”œβ”€β”€ sw.js # Service worker +β”œβ”€β”€ .nojekyll # Disable Jekyll +β”œβ”€β”€ .gitignore # Git ignore rules +β”œβ”€β”€ README.md # Documentation +β”œβ”€β”€ LICENSE # License file +└── .github/ + └── ISSUE_TEMPLATE/ + └── feature_request.md +``` + +## βš™οΈ Configuration Notes + +### Path Configuration + +All paths in the project are configured to work with: +- **Root deployment**: `https://username.github.io/ExpenseFlow/` +- **Custom domain**: `https://yourdomain.com/` + +The following files use relative paths for maximum compatibility: +- `manifest.json` - Uses `./` for relative paths +- `sw.js` - Uses relative paths for caching +- `trackerscript.js` - Dynamically detects base path for service worker + +### Service Worker + +The service worker is configured to: +- Work with both root and subdirectory deployments +- Automatically detect the base path +- Cache all necessary resources for offline functionality + +### PWA Manifest + +The manifest file is configured with: +- Relative start URL: `./index.html` +- Relative scope: `./` +- All icons use base64 encoded SVGs (no external dependencies) + +## πŸ”§ Troubleshooting + +### Service Worker Not Registering + +If the service worker fails to register: + +1. **Check browser console** for errors +2. **Verify file paths** are correct +3. **Clear browser cache** and reload +4. **Check HTTPS requirement** - Service workers require HTTPS (or localhost) + +### Assets Not Loading + +If CSS/JS files don't load: + +1. **Verify file names** match exactly (case-sensitive) +2. **Check file paths** in `index.html` +3. **Ensure `.nojekyll` file exists** to prevent Jekyll processing +4. **Clear GitHub Pages cache** (may take a few minutes) + +### PWA Not Installing + +If the PWA install prompt doesn't appear: + +1. **Check manifest.json** is accessible +2. **Verify HTTPS** is enabled (required for PWA) +3. **Check browser console** for manifest errors +4. **Ensure service worker** is registered successfully + +## 🌍 Other Hosting Options + +### Netlify + +1. Connect your GitHub repository to Netlify +2. Build command: (leave empty - static site) +3. Publish directory: `/` (root) +4. Deploy! + +### Vercel + +1. Import your GitHub repository +2. Framework preset: **Other** +3. Root directory: `./` +4. Deploy! + +### Firebase Hosting + +1. Install Firebase CLI: `npm install -g firebase-tools` +2. Initialize: `firebase init hosting` +3. Deploy: `firebase deploy` + +## πŸ“ Important Notes + +- **HTTPS Required**: PWA features require HTTPS (automatically provided by GitHub Pages) +- **Cache Busting**: Update `CACHE_NAME` in `sw.js` when deploying updates +- **File Names**: Keep file names lowercase and use hyphens for consistency +- **Relative Paths**: All internal paths use relative notation for portability + +## βœ… Deployment Checklist + +Before deploying, ensure: + +- [ ] All file paths are relative or properly configured +- [ ] `.nojekyll` file exists in root +- [ ] `.gitignore` is properly configured +- [ ] Service worker registration works +- [ ] Manifest.json is accessible +- [ ] All assets load correctly +- [ ] PWA features work (install prompt, offline mode) +- [ ] All navigation links work +- [ ] Responsive design works on mobile + +## πŸŽ‰ Post-Deployment + +After successful deployment: + +1. **Test all features** on the live site +2. **Verify PWA installation** works +3. **Check offline functionality** +4. **Test on multiple devices/browsers** +5. **Monitor browser console** for errors + +## πŸ“ž Support + +If you encounter issues: + +1. Check the [GitHub Issues](https://github.com/Renu-code123/ExpenseFlow-expensetracker/issues) +2. Review browser console for errors +3. Verify all file paths are correct +4. Ensure HTTPS is enabled + +--- + +**Happy Deploying! πŸš€** diff --git a/README.md b/README.md index aa5930de..60c53bdc 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,12 @@ With a clean and elegant dark-themed UI, it allows users to monitor spending, an ## 🧭 Table of Contents - [✨ Features](#-features) - [πŸ–₯️ Overview](#️-overview) +- [πŸ—οΈ Architecture & Flowcharts](#️-architecture--flowcharts) - [πŸ› οΈ Tech Stack](#️-tech-stack) - [πŸ“‚ Folder Structure](#-folder-structure) -- [πŸš€ How to Run Locally](#-how-to-run-locally) +- [πŸš€ Getting Started](#-getting-started) +- [πŸ“– Usage Guide](#-usage-guide) +- [πŸ”„ Data Flow](#-data-flow) - [πŸ“Έ Screenshots](#-screenshots) - [🧩 Future Enhancements](#-future-enhancements) - [🎯 Learning Outcomes](#-learning-outcomes) @@ -29,6 +32,9 @@ With a clean and elegant dark-themed UI, it allows users to monitor spending, an - πŸŒ™ **Dark Mode UI** – Sleek and eye-comfortable dark theme. - βš™οΈ **Responsive Design** – Optimized for desktop and mobile devices. - πŸ” **PWA Ready** – Manifest and service worker support for offline usage. +- πŸ” **Advanced Filtering** – Filter by category, date range, amount, and search. +- πŸ“₯ **Data Import/Export** – Export to CSV/JSON and import your data. +- πŸ”” **Real-time Notifications** – Get instant feedback on your actions. --- @@ -41,6 +47,398 @@ The app emphasizes: - User-centered design - Visual representation of financial data - Scalable project structure for future backend integration +- Progressive Web App (PWA) capabilities for offline functionality + +--- + +## πŸ—οΈ Architecture & Flowcharts + +### πŸ“ Application Architecture + +```mermaid +graph TB + subgraph "Client Layer" + A[User Interface
index.html] --> B[Styling Layer
expensetracker.css] + A --> C[Logic Layer
trackerscript.js] + end + + subgraph "Storage Layer" + D[LocalStorage
Browser Storage] + E[Service Worker Cache
sw.js] + end + + subgraph "PWA Layer" + F[Manifest.json
App Configuration] + G[Service Worker
Offline Support] + end + + C --> D + C --> E + A --> F + G --> E + G --> A + + style A fill:#64ffda,stroke:#0f0f23,stroke-width:3px + style C fill:#667eea,stroke:#0f0f23,stroke-width:2px + style D fill:#764ba2,stroke:#0f0f23,stroke-width:2px + style G fill:#f093fb,stroke:#0f0f23,stroke-width:2px +``` + +### πŸ”„ User Journey Flow + +```mermaid +flowchart TD + Start([User Opens App]) --> Load{App Loads} + Load --> Init[Initialize Application] + Init --> CheckData{Data in
LocalStorage?} + + CheckData -->|Yes| LoadData[Load Existing Transactions] + CheckData -->|No| EmptyState[Show Empty State] + + LoadData --> Dashboard[Display Dashboard] + EmptyState --> Dashboard + + Dashboard --> UserAction{User Action} + + UserAction -->|Add Transaction| AddForm[Show Add Form] + UserAction -->|View History| History[Display Transaction History] + UserAction -->|Filter/Search| Filter[Apply Filters] + UserAction -->|Export Data| Export[Export to CSV/JSON] + UserAction -->|Import Data| Import[Import from File] + + AddForm --> Validate{Validate Input} + Validate -->|Valid| SaveTransaction[Save Transaction] + Validate -->|Invalid| ShowError[Show Error Message] + ShowError --> AddForm + + SaveTransaction --> UpdateStorage[Update LocalStorage] + UpdateStorage --> UpdateUI[Update UI Display] + UpdateUI --> Notification[Show Success Notification] + Notification --> Dashboard + + History --> Filter + Filter --> DisplayFiltered[Display Filtered Results] + DisplayFiltered --> Dashboard + + Export --> DownloadFile[Download File] + DownloadFile --> Dashboard + + Import --> ParseFile[Parse File Data] + ParseFile --> MergeData{Merge with
Existing?} + MergeData -->|Yes| Merge[Merge Transactions] + MergeData -->|No| Replace[Replace Transactions] + Merge --> UpdateStorage + Replace --> UpdateStorage + + style Start fill:#64ffda,stroke:#0f0f23,stroke-width:3px + style Dashboard fill:#667eea,stroke:#0f0f23,stroke-width:2px + style SaveTransaction fill:#10ac84,stroke:#0f0f23,stroke-width:2px + style UpdateStorage fill:#764ba2,stroke:#0f0f23,stroke-width:2px +``` + +### πŸ’Ύ Data Flow Architecture + +```mermaid +sequenceDiagram + participant User + participant UI as User Interface + participant JS as JavaScript Logic + participant LS as LocalStorage + participant SW as Service Worker + participant Cache as Cache Storage + + User->>UI: Interacts with Form + UI->>JS: Form Submit Event + JS->>JS: Validate Input Data + JS->>JS: Create Transaction Object + JS->>LS: Save to LocalStorage + LS-->>JS: Confirm Save + JS->>UI: Update DOM Elements + JS->>UI: Show Notification + UI-->>User: Display Updated Balance + + Note over User,Cache: Offline Scenario + User->>UI: Request Resource + UI->>SW: Fetch Request + SW->>Cache: Check Cache + Cache-->>SW: Return Cached Resource + SW-->>UI: Serve Cached Content + UI-->>User: Display Content + + Note over User,Cache: Online Scenario + User->>UI: Request Resource + UI->>SW: Fetch Request + SW->>Cache: Check Cache + Cache-->>SW: Not Found + SW->>Network: Fetch from Network + Network-->>SW: Return Resource + SW->>Cache: Store in Cache + SW-->>UI: Serve Resource + UI-->>User: Display Content +``` + +### 🧩 Component Interaction Flow + +```mermaid +graph LR + subgraph "UI Components" + A[Balance Card] + B[Income Card] + C[Expense Card] + D[Transaction List] + E[Add Form] + F[Filter Controls] + G[Export/Import] + end + + subgraph "JavaScript Functions" + H[updateValues] + I[displayTransactions] + J[addTransaction] + K[removeTransaction] + L[getFilteredTransactions] + M[exportDataToCSV] + N[importDataFromFile] + end + + subgraph "Data Storage" + O[transactions Array] + P[LocalStorage] + end + + A --> H + B --> H + C --> H + D --> I + E --> J + F --> L + G --> M + G --> N + + H --> O + I --> L + J --> O + K --> O + L --> O + M --> O + N --> O + + O --> P + P --> O + + style A fill:#64ffda,stroke:#0f0f23,stroke-width:2px + style B fill:#10ac84,stroke:#0f0f23,stroke-width:2px + style C fill:#ff6b6b,stroke:#0f0f23,stroke-width:2px + style O fill:#764ba2,stroke:#0f0f23,stroke-width:2px + style P fill:#667eea,stroke:#0f0f23,stroke-width:2px +``` + +### πŸ”„ Transaction Processing Flow + +```mermaid +flowchart TD + Start([User Submits Form]) --> Validate{Validate Fields} + + Validate -->|Missing Fields| Error1[Show Error:
Fill All Fields] + Validate -->|Invalid Amount| Error2[Show Error:
Valid Amount Required] + Validate -->|Valid| Process[Process Transaction] + + Error1 --> End1([Return to Form]) + Error2 --> End1 + + Process --> CreateObj[Create Transaction Object] + CreateObj --> SetID[Generate Unique ID] + SetID --> SetType{Transaction Type?} + + SetType -->|Income| SetPositive[Set Positive Amount] + SetType -->|Expense| SetNegative[Set Negative Amount] + + SetPositive --> AddDate[Add Timestamp] + SetNegative --> AddDate + + AddDate --> AddCategory[Add Category Info] + AddCategory --> PushArray[Push to Transactions Array] + + PushArray --> UpdateStorage[Update LocalStorage] + UpdateStorage --> UpdateBalance[Recalculate Balance] + UpdateBalance --> UpdateIncome[Recalculate Income] + UpdateIncome --> UpdateExpense[Recalculate Expense] + + UpdateExpense --> FilterData[Apply Active Filters] + FilterData --> RenderList[Render Transaction List] + RenderList --> ClearForm[Clear Form Fields] + ClearForm --> ShowSuccess[Show Success Notification] + ShowSuccess --> End2([Transaction Added]) + + style Start fill:#64ffda,stroke:#0f0f23,stroke-width:3px + style Process fill:#667eea,stroke:#0f0f23,stroke-width:2px + style UpdateStorage fill:#764ba2,stroke:#0f0f23,stroke-width:2px + style End2 fill:#10ac84,stroke:#0f0f23,stroke-width:3px + style Error1 fill:#ff6b6b,stroke:#0f0f23,stroke-width:2px + style Error2 fill:#ff6b6b,stroke:#0f0f23,stroke-width:2px +``` + +### πŸ“± PWA Lifecycle Flow + +```mermaid +stateDiagram-v2 + [*] --> NotInstalled: App Loaded + + NotInstalled --> InstallPrompt: beforeinstallprompt Event + InstallPrompt --> Installing: User Clicks Install + InstallPrompt --> Dismissed: User Dismisses + + Installing --> Installed: Installation Complete + Installed --> Registered: Service Worker Registered + + Registered --> Caching: Cache Resources + Caching --> Active: Service Worker Active + Active --> Online: App Online + + Online --> Offline: Network Disconnected + Offline --> Cached: Serve from Cache + Cached --> Online: Network Reconnected + + Active --> UpdateAvailable: New Version Detected + UpdateAvailable --> UpdatePrompt: Show Update Notification + UpdatePrompt --> Updating: User Clicks Update + Updating --> Updated: Update Complete + Updated --> Reload: Reload Page + + Dismissed --> NotInstalled + Reload --> Active + + note right of Active + Service Worker handles: + - Caching + - Offline Support + - Background Sync + - Push Notifications + end note +``` + +### πŸ” Filtering & Search Flow + +```mermaid +flowchart TD + Start([User Applies Filter]) --> GetFilter{Filter Type} + + GetFilter -->|Type Filter| TypeFilter[Filter by Income/Expense] + GetFilter -->|Category Filter| CategoryFilter[Filter by Category] + GetFilter -->|Search Query| SearchFilter[Filter by Text Search] + GetFilter -->|Date Range| DateFilter[Filter by Date Range] + GetFilter -->|Amount Range| AmountFilter[Filter by Amount] + GetFilter -->|Clear All| ClearFilters[Reset All Filters] + + TypeFilter --> Combine[Combine All Active Filters] + CategoryFilter --> Combine + SearchFilter --> Combine + DateFilter --> Combine + AmountFilter --> Combine + ClearFilters --> Combine + + Combine --> ApplyFilters[Apply Filters to Transactions] + ApplyFilters --> CheckResults{Results Found?} + + CheckResults -->|Yes| SortByDate[Sort by Date Descending] + CheckResults -->|No| ShowEmpty[Show Empty State Message] + + SortByDate --> RenderTransactions[Render Filtered Transactions] + RenderTransactions --> UpdateCount[Update Result Count] + UpdateCount --> End([Display Results]) + + ShowEmpty --> End + + style Start fill:#64ffda,stroke:#0f0f23,stroke-width:3px + style Combine fill:#667eea,stroke:#0f0f23,stroke-width:2px + style RenderTransactions fill:#10ac84,stroke:#0f0f23,stroke-width:2px + style ShowEmpty fill:#ff6b6b,stroke:#0f0f23,stroke-width:2px +``` + +### πŸ“₯ Export/Import Data Flow + +```mermaid +flowchart LR + subgraph "Export Flow" + A1[User Clicks Export] --> A2{Export Format?} + A2 -->|CSV| A3[Convert to CSV] + A2 -->|JSON| A4[Convert to JSON] + A3 --> A5[Create Blob] + A4 --> A5 + A5 --> A6[Create Download Link] + A6 --> A7[Trigger Download] + A7 --> A8[Show Success Notification] + end + + subgraph "Import Flow" + B1[User Selects File] --> B2{File Type?} + B2 -->|CSV| B3[Parse CSV Data] + B2 -->|JSON| B4[Parse JSON Data] + B3 --> B5[Validate Data] + B4 --> B5 + B5 --> B6{Valid Data?} + B6 -->|No| B7[Show Error] + B6 -->|Yes| B8{Merge Option?} + B8 -->|Merge| B9[Add to Existing] + B8 -->|Replace| B10[Replace All] + B9 --> B11[Update LocalStorage] + B10 --> B11 + B11 --> B12[Refresh UI] + B12 --> B13[Show Success Notification] + end + + style A1 fill:#64ffda,stroke:#0f0f23,stroke-width:2px + style A7 fill:#10ac84,stroke:#0f0f23,stroke-width:2px + style B1 fill:#64ffda,stroke:#0f0f23,stroke-width:2px + style B11 fill:#764ba2,stroke:#0f0f23,stroke-width:2px + style B7 fill:#ff6b6b,stroke:#0f0f23,stroke-width:2px +``` + +### 🎨 State Management Flow + +```mermaid +stateDiagram-v2 + [*] --> InitialState: App Initialization + + InitialState --> LoadingState: Fetch from LocalStorage + LoadingState --> LoadedState: Data Loaded + + LoadedState --> AddingTransaction: User Adds Transaction + AddingTransaction --> Validating: Validate Input + Validating --> Valid: Input Valid + Validating --> Invalid: Input Invalid + + Valid --> Saving: Save to Storage + Invalid --> ErrorState: Show Error + ErrorState --> AddingTransaction: Retry + + Saving --> Saved: Transaction Saved + Saved --> UpdatingUI: Update UI + UpdatingUI --> LoadedState: Return to Loaded + + LoadedState --> Filtering: User Applies Filter + Filtering --> FilteredState: Display Filtered Results + FilteredState --> LoadedState: Clear Filter + + LoadedState --> Deleting: User Deletes Transaction + Deleting --> Deleted: Transaction Deleted + Deleted --> UpdatingUI + + LoadedState --> Exporting: User Exports Data + Exporting --> Exported: Data Exported + Exported --> LoadedState + + LoadedState --> Importing: User Imports Data + Importing --> Imported: Data Imported + Imported --> UpdatingUI + + note right of LoadedState + Main Application State + - Transactions Array + - Filter Settings + - UI State + end note +``` --- @@ -49,53 +447,168 @@ The app emphasizes: | Category | Technology Used | |-----------|------------------| | **Frontend** | HTML5, CSS3, JavaScript (Vanilla JS) | -| **Styling** | Tailwind CSS / Custom CSS | +| **Styling** | Custom CSS with CSS Variables | +| **Icons** | Font Awesome 6.4.0 | +| **Fonts** | Google Fonts (Inter) | +| **Storage** | LocalStorage API | +| **PWA** | Service Workers, Web App Manifest | | **Version Control** | Git, GitHub | | **Deployment** | GitHub Pages | -| **PWA Support** | manifest.json, sw.js | --- ## πŸ“‚ Folder Structure -```tree -ExpenseFlow-expensetracker/ +``` +ExpenseFlow/ β”‚ -β”œβ”€β”€ expenseTracker.html # Main HTML layout -β”œβ”€β”€ expenseTracker.css # Styling and UI components -β”œβ”€β”€ trackerScript.js # Core JavaScript functionality -β”œβ”€β”€ manifest.json # Manifest file for PWA -β”œβ”€β”€ sw.js # Service Worker for offline caching -β”œβ”€β”€ LICENSE # MIT License -└── README.md # Documentation +β”œβ”€β”€ index.html # Main HTML layout +β”œβ”€β”€ expensetracker.css # Styling and UI components +β”œβ”€β”€ trackerscript.js # Core JavaScript functionality +β”œβ”€β”€ manifest.json # PWA Manifest file +β”œβ”€β”€ sw.js # Service Worker for offline caching +β”œβ”€β”€ LICENSE # MIT License +β”œβ”€β”€ README.md # Project documentation +β”œβ”€β”€ CONTRIBUTING.md # Contribution guidelines +β”œβ”€β”€ Code_of_conduct.md # Code of conduct +└── .github/ + └── ISSUE_TEMPLATE/ + └── feature_request.md # Feature request template ``` --- -## πŸš€ How to Run Locally +## πŸš€ Getting Started + +### Prerequisites + +- A modern web browser (Chrome, Firefox, Safari, Edge) +- A code editor (VS Code, Sublime Text, etc.) +- Git (optional, for version control) + +### Installation + +Follow these simple steps to set up and view the project on your local machine: -Follow these simple steps to set up and view the project on your local machine πŸ‘‡ +#### 1️⃣ Clone the Repository -### 1️⃣ Clone the Repository ```bash git clone https://github.com/Renu-code123/ExpenseFlow-expensetracker.git ``` -### 2️⃣ Navigate into the Project Folder +#### 2️⃣ Navigate into the Project Folder ```bash cd ExpenseFlow-expensetracker ``` -#3️⃣ Open the HTML File -Simply open the expenseTracker.html file in your browser. +#### 3️⃣ Open the Application -or run a live development server using: +**Option A: Direct Browser Opening** +- Simply open the `index.html` file in your browser. + +**Option B: Using Live Server (Recommended)** ```bash +# Using npx (no installation needed) npx live-server ``` +# Or install globally +npm install -g live-server +live-server +``` + +The application will automatically open in your default browser at `http://localhost:8080` + +#### 4️⃣ PWA Installation (Optional) + +1. Open the application in a supported browser +2. Look for the install prompt or browser's install option +3. Click "Install" to add ExpenseFlow to your home screen +4. Enjoy offline functionality! + +--- + +## πŸ“– Usage Guide + +### Adding a Transaction + +1. Scroll to the "Add New Transaction" section +2. Fill in the transaction details: + - **Description**: Enter a brief description (e.g., "Grocery Shopping") + - **Category**: Select from available categories + - **Amount**: Enter the transaction amount + - **Type**: Select "Income" or "Expense" +3. Click "Add Transaction" +4. The transaction will appear in your history and update your balance + +### Filtering Transactions + +- **Type Filter**: Click "All", "Income", or "Expense" buttons +- **Category Filter**: Select a category from the dropdown +- **Search**: Type in the search box to find specific transactions +- **Date Range**: Select "From" and "To" dates +- **Amount Range**: Enter minimum and maximum amounts +- **Clear Filters**: Click "Clear Filters" to reset all filters + +### Exporting Data + +1. Scroll to the "Data Management" section +2. Click "Export to CSV" or "Export to JSON" +3. The file will download automatically +4. Use this file for backup or analysis in spreadsheet applications + +### Importing Data + +1. Scroll to the "Data Management" section +2. Click "Choose File" and select a CSV or JSON file +3. Choose whether to merge with existing data or replace it +4. Click "Import Data" +5. Your transactions will be imported and displayed + +### Deleting Transactions + +- Click the trash icon (πŸ—‘οΈ) next to any transaction +- The transaction will be removed and your balance will update + +--- + +## πŸ”„ Data Flow + +### Transaction Data Structure + +```javascript +{ + id: 123456789, // Unique identifier + text: "Grocery Shopping", // Transaction description + amount: -2500.00, // Amount (negative for expenses) + category: "food", // Category key + type: "expense", // Transaction type + date: "2025-01-15T10:30:00.000Z" // ISO timestamp +} +``` + +### Storage Flow + +```mermaid +graph LR + A[User Input] --> B[Form Validation] + B --> C[Create Transaction Object] + C --> D[Add to Transactions Array] + D --> E[Stringify to JSON] + E --> F[Save to LocalStorage] + F --> G[Update UI] + G --> H[Display Notification] + + style A fill:#64ffda,stroke:#0f0f23,stroke-width:2px + style D fill:#667eea,stroke:#0f0f23,stroke-width:2px + style F fill:#764ba2,stroke:#0f0f23,stroke-width:2px + style G fill:#10ac84,stroke:#0f0f23,stroke-width:2px +``` + +--- + ## πŸ“Έ Screenshots image image @@ -104,61 +617,65 @@ npx live-server ### 🏠 Dashboard Preview **Smart Money Management – Take control of your finances with our intuitive expense tracker.** +*Note: Add your screenshots here to showcase the application* + --- ## 🧩 Future Enhancements -- πŸ”— Add backend for real-time data persistence (Firebase or Node.js) -- πŸ“Š Integrate charting tools like Chart.js for expense visualization -- 🧾 Introduce login/authentication system -- πŸ’‘ Add category filters for detailed analysis -- πŸ“± Improve PWA support for full offline functionality +- πŸ”— **Backend Integration** – Add backend for real-time data persistence (Firebase or Node.js) +- πŸ“Š **Advanced Charts** – Integrate charting tools like Chart.js for expense visualization +- πŸ” **Authentication** – Introduce login/authentication system +- πŸ’‘ **Budget Management** – Add budget limits and alerts for categories +- πŸ“± **Mobile App** – Native mobile app using React Native or Flutter +- 🌍 **Multi-currency Support** – Support for multiple currencies +- πŸ“§ **Email Reports** – Weekly/monthly expense reports via email +- πŸ€– **AI Insights** – AI-powered spending insights and recommendations +- πŸ”” **Push Notifications** – Reminders for bill payments and budget limits +- πŸ“ˆ **Investment Tracking** – Track investments and portfolio performance --- ## 🎯 Learning Outcomes -By building this project, you’ll learn: +By building this project, you'll learn: -- 🎨 Responsive UI design using CSS -- 🧠 DOM manipulation using vanilla JavaScript -- πŸ“‚ Managing and displaying dynamic user data -- βš™οΈ Working with manifests and service workers -- πŸ—οΈ Structuring a scalable frontend project +- 🎨 **Responsive UI Design** – Creating beautiful, responsive interfaces using CSS +- 🧠 **DOM Manipulation** – Working with the Document Object Model using vanilla JavaScript +- πŸ“‚ **Data Management** – Managing and displaying dynamic user data +- πŸ’Ύ **Local Storage** – Persisting data using the LocalStorage API +- βš™οΈ **PWA Development** – Working with manifests and service workers +- πŸ—οΈ **Project Structure** – Structuring a scalable frontend project +- πŸ”„ **State Management** – Managing application state without frameworks +- 🎯 **Event Handling** – Handling user interactions and events +- πŸ“Š **Data Visualization** – Displaying financial data in an intuitive way +- πŸ§ͺ **Error Handling** – Implementing proper error handling and validation --- ## 🀝 Contributing Contributions are always welcome! -If you’d like to improve **ExpenseFlow**, follow these steps πŸ‘‡ +If you'd like to improve **ExpenseFlow**, follow these steps: 1. **Fork the repository** 2. **Create a new branch** ```bash git checkout -b feature-name - ``` - + ``` 3. **Commit your changes** -```bash -git commit -m "Added a new feature" -``` - + ```bash + git commit -m "Added a new feature" + ``` 4. **Push to your branch** -```bash -git push origin feature-name -``` - -7. **Open a Pull Request** + ```bash + git push origin feature-name + ``` +5. **Open a Pull Request** +For detailed contribution guidelines, please read [CONTRIBUTING.md](./CONTRIBUTING.md) - -## How to Use ExpenseFlow - -1. Open the application in your browser. -2. Add a new expense using the expense input form. -3. View all added expenses in the dashboard. -4. Track and manage your daily spending easily. +--- ## 🧾 License This project is licensed under the **MIT License** – see the [LICENSE](./LICENSE) file for details. @@ -171,10 +688,11 @@ This project is licensed under the **MIT License** – see the [LICENSE](./LICEN πŸ“« **Connect with me:** - **GitHub:** [@Renu-code123](https://github.com/Renu-code123) + --- ## πŸ’¬ Quote -> β€œSmart money management begins with awareness β€” track it, plan it, and grow it with **ExpenseFlow**.” +> "Smart money management begins with awareness β€” track it, plan it, and grow it with **ExpenseFlow**." --- diff --git a/expensetracker.css b/expensetracker.css index 654f5121..b63504aa 100644 --- a/expensetracker.css +++ b/expensetracker.css @@ -24,6 +24,11 @@ --error: #ff5722; --warning: #ffc107; + /* Typography */ + --font-primary: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --font-heading: 'Space Grotesk', 'Poppins', sans-serif; + --font-body: 'Inter', 'Poppins', -apple-system, BlinkMacSystemFont, sans-serif; + /* Shadows */ --shadow-glass: 0 8px 32px 0 rgba(31, 38, 135, 0.37); --shadow-hover: 0 15px 35px rgba(0, 0, 0, 0.1); @@ -53,7 +58,7 @@ html { } body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + font-family: var(--font-body); background: var(--bg-primary); background-image: radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), @@ -61,8 +66,16 @@ body { radial-gradient(circle at 40% 40%, rgba(100, 255, 218, 0.2) 0%, transparent 50%); min-height: 100vh; color: var(--text-primary); - line-height: 1.6; + line-height: 1.7; overflow-x: hidden; + margin: 0; + padding: 0; + width: 100%; + box-sizing: border-box; + font-weight: 400; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; } /* Header Styles */ @@ -93,9 +106,12 @@ body { display: flex; align-items: center; gap: 0.5rem; + font-family: var(--font-heading); font-size: 1.5rem; font-weight: 700; color: var(--accent-primary); + letter-spacing: -0.5px; + text-transform: none; } .nav-logo i { @@ -115,11 +131,16 @@ body { .nav-link { color: var(--text-secondary); text-decoration: none; - font-weight: 500; + font-family: var(--font-primary); + font-weight: 600; + font-size: 0.95rem; + letter-spacing: 0.3px; padding: 0.5rem 1rem; border-radius: 0.5rem; transition: all 0.3s ease; position: relative; + text-transform: uppercase; + font-size: 0.85rem; } .nav-link:hover, @@ -142,8 +163,11 @@ body { } .username { - font-weight: 500; + font-family: var(--font-primary); + font-weight: 600; + font-size: 0.95rem; color: var(--text-primary); + letter-spacing: 0.2px; } .nav-toggle { @@ -163,60 +187,111 @@ body { /* Main Content */ .main-content { - padding-top: 100px; + padding-top: 120px; min-height: 100vh; + width: 100%; + overflow-x: hidden; } .hero-section { text-align: center; padding: 3rem 2rem; max-width: 800px; - margin: 0 auto; + margin: 0 auto 2rem auto; + width: 100%; + box-sizing: border-box; } .hero-title { - font-size: 3.5rem; - font-weight: 700; + font-family: var(--font-heading); + font-size: 4rem; + font-weight: 800; background: var(--primary-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 1rem; animation: fadeInUp 1s ease-out; + letter-spacing: -1.5px; + line-height: 1.1; + text-transform: none; } .hero-subtitle { - font-size: 1.2rem; + font-family: var(--font-body); + font-size: 1.3rem; + font-weight: 400; color: var(--text-secondary); margin-bottom: 2rem; animation: fadeInUp 1s ease-out 0.2s both; + letter-spacing: 0.2px; + line-height: 1.6; } .container { width: 100%; max-width: 1100px; margin: 0 auto; + padding: 0 2rem; + display: flex; + flex-direction: column; + gap: 2rem; + margin-bottom: 4rem; + width: 100%; + box-sizing: border-box; } -/* Balance Card */ +/* Balance Card - Redesigned */ .balance-card { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(20px); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 2rem; + background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); + backdrop-filter: blur(30px); + border-radius: 24px; + border: 2px solid transparent; + background-clip: padding-box; + padding: 2.5rem; text-align: center; - box-shadow: var(--shadow-glass); - transition: transform 0.3s ease, box-shadow 0.3s ease; + position: relative; + overflow: hidden; + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(255, 255, 255, 0.1) inset, + 0 0 60px rgba(100, 255, 218, 0.1); + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); animation: fadeInUp 1s ease-out 0.4s both; width: 100%; + box-sizing: border-box; + margin-bottom: 0; +} + +.balance-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, + transparent, + var(--accent-primary), + transparent + ); + opacity: 0; + transition: opacity 0.4s ease; max-width: 24rem; margin: 0 auto; } .balance-card:hover { - transform: translateY(-5px); - box-shadow: var(--shadow-hover); + transform: translateY(-8px) scale(1.02); + box-shadow: + 0 20px 60px rgba(0, 0, 0, 0.5), + 0 0 0 1px rgba(255, 255, 255, 0.2) inset, + 0 0 80px rgba(100, 255, 218, 0.2); + border-color: rgba(100, 255, 218, 0.3); +} + +.balance-card:hover::before { + opacity: 1; } .balance-header { @@ -233,19 +308,23 @@ body { } .balance-header h4 { + font-family: var(--font-heading); color: var(--text-secondary); - font-weight: 500; + font-weight: 600; text-transform: uppercase; - letter-spacing: 1px; - font-size: 0.9rem; + letter-spacing: 2px; + font-size: 0.85rem; } .balance-amount { - font-size: 3rem; - font-weight: 700; + font-family: var(--font-heading); + font-size: 3.5rem; + font-weight: 800; color: var(--text-primary); margin: 1rem 0; text-shadow: 0 0 20px rgba(100, 255, 218, 0.3); + letter-spacing: -1px; + line-height: 1.2; } .balance-trend { @@ -274,6 +353,10 @@ body { display: grid; grid-template-columns: 1fr; gap: 1.5rem; + animation: fadeInUp 1s ease-out 0.6s both; + width: 100%; + box-sizing: border-box; + margin-bottom: 0; width: 100%; margin-bottom: 2rem; } @@ -287,13 +370,43 @@ body { .income-card, .expense-card { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(20px); - border-radius: 15px; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 1.5rem; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.03) 100%); + backdrop-filter: blur(25px); + border-radius: 20px; + border: 2px solid transparent; + background-clip: padding-box; + padding: 2rem; display: flex; align-items: center; + gap: 1.5rem; + position: relative; + overflow: hidden; + box-shadow: + 0 8px 24px rgba(0, 0, 0, 0.3), + 0 0 0 1px rgba(255, 255, 255, 0.08) inset; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.income-card::before, +.expense-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle at top right, rgba(100, 255, 218, 0.1), transparent 70%); + opacity: 0; + transition: opacity 0.4s ease; + pointer-events: none; +} + +.income-card { + border-left: 3px solid var(--success); +} + +.expense-card { + border-left: 3px solid var(--error); gap: 1rem; box-shadow: var(--shadow-glass); transition: all 0.3s ease; @@ -304,19 +417,37 @@ body { .income-card:hover, .expense-card:hover { - transform: translateY(-3px); - box-shadow: var(--shadow-hover); + transform: translateY(-6px) scale(1.03); + box-shadow: + 0 16px 40px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(255, 255, 255, 0.15) inset, + 0 0 40px rgba(100, 255, 218, 0.15); + border-color: rgba(255, 255, 255, 0.2); +} + +.income-card:hover::before, +.expense-card:hover::before { + opacity: 1; } .card-icon { - width: 60px; - height: 60px; - border-radius: 15px; + width: 70px; + height: 70px; + border-radius: 18px; display: flex; align-items: center; justify-content: center; - font-size: 1.5rem; + font-size: 1.75rem; color: white; + position: relative; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.income-card:hover .card-icon, +.expense-card:hover .card-icon { + transform: scale(1.1) rotate(5deg); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); } .income-icon { @@ -328,35 +459,73 @@ body { } .card-content h4 { + font-family: var(--font-heading); color: var(--text-secondary); - font-size: 0.9rem; - font-weight: 500; + font-size: 0.85rem; + font-weight: 600; text-transform: uppercase; - letter-spacing: 1px; + letter-spacing: 2px; margin-bottom: 0.5rem; } .money-plus { + font-family: var(--font-heading); color: var(--success); - font-size: 1.5rem; - font-weight: 600; + font-size: 1.75rem; + font-weight: 700; + letter-spacing: -0.5px; } .money-minus { + font-family: var(--font-heading); color: var(--error); - font-size: 1.5rem; - font-weight: 600; + font-size: 1.75rem; + font-weight: 700; + letter-spacing: -0.5px; } -/* History Section */ +/* History Section - Redesigned */ .history-section { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(20px); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 2rem; - box-shadow: var(--shadow-glass); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.03) 100%); + backdrop-filter: blur(30px); + border-radius: 24px; + border: 2px solid transparent; + background-clip: padding-box; + padding: 2.5rem; + position: relative; + overflow: hidden; + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(255, 255, 255, 0.1) inset; animation: fadeInUp 1s ease-out 0.8s both; + width: 100%; + box-sizing: border-box; + margin-top: 0; + margin-bottom: 0; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.history-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, + transparent, + var(--accent-primary), + transparent + ); + opacity: 0.5; +} + +.history-section:hover { + box-shadow: + 0 12px 40px rgba(0, 0, 0, 0.5), + 0 0 0 1px rgba(255, 255, 255, 0.15) inset, + 0 0 60px rgba(100, 255, 218, 0.1); + border-color: rgba(100, 255, 218, 0.2); } .section-header { @@ -367,15 +536,17 @@ body { } .section-header h3 { + font-family: var(--font-heading); color: var(--text-primary); - font-size: 1.3rem; - font-weight: 600; + font-size: 1.5rem; + font-weight: 700; display: flex; align-items: center; gap: 0.5rem; border-bottom: none; padding-bottom: 0; margin: 0; + letter-spacing: -0.3px; } .section-header h3 i { @@ -507,6 +678,7 @@ body { } .filter-btn { + font-family: var(--font-primary); padding: 0.5rem 1rem; border: 1px solid rgba(255, 255, 255, 0.2); background: transparent; @@ -515,7 +687,9 @@ body { cursor: pointer; transition: all 0.3s ease; font-size: 0.9rem; - font-weight: 500; + font-weight: 600; + letter-spacing: 0.5px; + text-transform: uppercase; } .filter-btn:hover, @@ -549,25 +723,46 @@ body { } .list li { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(10px); - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 1rem; - margin-bottom: 0.5rem; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.03) 100%); + backdrop-filter: blur(20px); + border-radius: 16px; + border: 2px solid transparent; + background-clip: padding-box; + padding: 1.25rem 1.5rem; + margin-bottom: 0.75rem; display: flex; justify-content: space-between; align-items: center; position: relative; - transition: all 0.3s ease; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); animation: slideInLeft 0.3s ease-out; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + overflow: hidden; +} + +.list li::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 4px; + background: currentColor; + transition: width 0.4s ease; + z-index: 0; max-width: 100%; word-break: break-word; } .list li:hover { - transform: translateX(5px); - background: rgba(255, 255, 255, 0.1); + transform: translateX(8px) translateY(-2px); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.06) 100%); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3); + border-color: rgba(255, 255, 255, 0.2); +} + +.list li:hover::before { + width: 6px; } .list li.plus { @@ -609,13 +804,46 @@ body { /* Data Management Section */ .data-management-section { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(20px); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 2rem; - box-shadow: var(--shadow-glass); + background: linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%); + backdrop-filter: blur(30px); + border-radius: 24px; + border: 2px solid transparent; + background-clip: padding-box; + padding: 2.5rem; + position: relative; + overflow: hidden; + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(255, 255, 255, 0.1) inset; + width: 100%; + box-sizing: border-box; + margin-top: 0; + margin-bottom: 0; animation: fadeInUp 1s ease-out 0.9s both; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.data-management-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, + transparent, + var(--accent-primary), + transparent + ); + opacity: 0.5; +} + +.data-management-section:hover { + box-shadow: + 0 12px 40px rgba(0, 0, 0, 0.5), + 0 0 0 1px rgba(255, 255, 255, 0.15) inset, + 0 0 60px rgba(100, 255, 218, 0.1); + border-color: rgba(100, 255, 218, 0.2); } .data-management-section h3 { @@ -753,27 +981,62 @@ body { accent-color: var(--accent-primary); } -/* Form Section */ +/* Form Section - Redesigned */ .form-section { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(20px); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 2rem; - box-shadow: var(--shadow-glass); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.03) 100%); + backdrop-filter: blur(30px); + border-radius: 24px; + border: 2px solid transparent; + background-clip: padding-box; + padding: 2.5rem; + position: relative; + overflow: hidden; + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(255, 255, 255, 0.1) inset; animation: fadeInUp 1s ease-out 1s both; + width: 100%; + box-sizing: border-box; + margin-top: 0; + margin-bottom: 0; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.form-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, + transparent, + var(--accent-primary), + transparent + ); + opacity: 0.5; +} + +.form-section:hover { + box-shadow: + 0 12px 40px rgba(0, 0, 0, 0.5), + 0 0 0 1px rgba(255, 255, 255, 0.15) inset, + 0 0 60px rgba(100, 255, 218, 0.1); + border-color: rgba(100, 255, 218, 0.2); } .form-section h3 { + font-family: var(--font-heading); color: var(--text-primary); - font-size: 1.3rem; - font-weight: 600; + font-size: 1.5rem; + font-weight: 700; display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1.5rem; border-bottom: none; padding-bottom: 0; + letter-spacing: -0.3px; } .form-section h3 i { @@ -799,14 +1062,16 @@ body { } .form-control label { + font-family: var(--font-heading); color: var(--text-secondary); - font-weight: 500; - font-size: 0.9rem; + font-weight: 600; + font-size: 0.85rem; text-transform: uppercase; - letter-spacing: 1px; + letter-spacing: 1.5px; } .form-control input { + font-family: var(--font-body); padding: 1rem; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 10px; @@ -814,7 +1079,9 @@ body { backdrop-filter: blur(10px); color: var(--text-primary); font-size: 1rem; + font-weight: 400; transition: all 0.3s ease; + letter-spacing: 0.2px; } .form-control input:focus { @@ -828,6 +1095,7 @@ body { } .form-control select { + font-family: var(--font-body); padding: 1rem; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 10px; @@ -835,8 +1103,10 @@ body { backdrop-filter: blur(10px); color: var(--text-primary); font-size: 1rem; + font-weight: 400; transition: all 0.3s ease; cursor: pointer; + letter-spacing: 0.2px; } .form-control select:focus { @@ -858,13 +1128,14 @@ body { } .btn-submit { + font-family: var(--font-heading); padding: 1rem 2rem; background: var(--primary-gradient); color: white; border: none; border-radius: 10px; font-size: 1rem; - font-weight: 600; + font-weight: 700; cursor: pointer; transition: all 0.3s ease; display: flex; @@ -872,7 +1143,7 @@ body { justify-content: center; gap: 0.5rem; text-transform: uppercase; - letter-spacing: 1px; + letter-spacing: 2px; } .btn-submit:hover { @@ -1223,6 +1494,39 @@ body { .data-actions { grid-template-columns: 1fr; } + + .container { + gap: 1.5rem; + } + + .main-content { + padding-top: 100px; + } + + .hero-section { + padding: 2rem 1rem; + } + + .hero-title { + font-size: 2.5rem; + } + + .inc-exp-container { + grid-template-columns: 1fr; + gap: 1rem; + } + + .balance-card, + .history-section, + .data-management-section, + .form-section { + padding: 1.5rem; + } + + .app-section { + width: 100%; + overflow-x: hidden; + } } /* PWA Install Prompt */ @@ -1466,13 +1770,673 @@ body { } } -/* ===== GLOBAL LOADER ===== */ -.global-loader { - position: fixed; - top: 0; - left: 0; +/* Section Navigation Styles */ +.app-section { + display: none; + animation: fadeIn 0.5s ease-in-out; width: 100%; - height: 100%; + box-sizing: border-box; + position: relative; +} + +.app-section.active { + display: block; + width: 100%; + box-sizing: border-box; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.section-header { + margin-bottom: 2rem; + text-align: center; +} + +.section-header h2 { + font-size: 2.5rem; + margin-bottom: 0.5rem; + color: var(--accent-primary); + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; +} + +.section-description { + color: var(--text-secondary); + font-size: 1.1rem; +} + +/* Analytics Section */ +.analytics-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-bottom: 2rem; +} + +.analytics-card { + background: var(--bg-secondary); + border-radius: 20px; + padding: 2rem; + border: 1px solid rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.analytics-card:hover { + transform: translateY(-5px); + box-shadow: var(--shadow-card); +} + +.analytics-card-header { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1.5rem; + padding-bottom: 1rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.analytics-card-header i { + font-size: 2rem; + color: var(--accent-primary); +} + +.analytics-card-header h3 { + font-size: 1.5rem; + color: var(--text-primary); +} + +.chart-placeholder { + text-align: center; + padding: 3rem 1rem; + color: var(--text-secondary); +} + +.chart-placeholder i { + margin-bottom: 1rem; + opacity: 0.5; +} + +.category-list { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.category-stat-item { + padding: 1rem; + background: rgba(255, 255, 255, 0.05); + border-radius: 10px; +} + +.category-stat-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.5rem; +} + +.category-icon { + font-size: 1.1rem; +} + +.category-total { + font-weight: 600; + color: var(--accent-primary); +} + +.category-stat-bars { + display: flex; + height: 8px; + border-radius: 4px; + overflow: hidden; + background: rgba(255, 255, 255, 0.1); +} + +.stat-bar { + height: 100%; + transition: width 0.3s ease; +} + +.income-bar { + background: var(--success); +} + +.expense-bar { + background: var(--error); +} + +.analytics-summary { + margin-top: 2rem; +} + +.summary-card { + background: var(--bg-secondary); + border-radius: 20px; + padding: 2rem; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.summary-card h4 { + font-size: 1.5rem; + margin-bottom: 1.5rem; + color: var(--accent-primary); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1.5rem; +} + +.stat-item { + display: flex; + flex-direction: column; + gap: 0.5rem; + padding: 1rem; + background: rgba(255, 255, 255, 0.05); + border-radius: 10px; +} + +.stat-label { + font-size: 0.9rem; + color: var(--text-secondary); +} + +.stat-value { + font-size: 1.5rem; + font-weight: 700; + color: var(--accent-primary); +} + +/* Goals Section */ +.goals-container { + max-width: 1200px; + margin: 0 auto; +} + +.goals-header-actions { + margin-bottom: 2rem; + display: flex; + justify-content: flex-end; +} + +.goals-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 2rem; +} + +.goal-card { + background: var(--bg-secondary); + border-radius: 20px; + padding: 2rem; + border: 1px solid rgba(255, 255, 255, 0.1); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.goal-card:hover { + transform: translateY(-5px); + box-shadow: var(--shadow-card); +} + +.goal-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1.5rem; +} + +.goal-header h3 { + font-size: 1.5rem; + color: var(--text-primary); +} + +.goal-delete { + background: transparent; + border: none; + color: var(--error); + cursor: pointer; + padding: 0.5rem; + border-radius: 5px; + transition: background 0.3s ease; +} + +.goal-delete:hover { + background: rgba(255, 87, 34, 0.2); +} + +.goal-progress { + margin-bottom: 1.5rem; +} + +.progress-bar { + height: 12px; + background: rgba(255, 255, 255, 0.1); + border-radius: 10px; + overflow: hidden; + margin-bottom: 0.5rem; +} + +.progress-fill { + height: 100%; + background: var(--primary-gradient); + border-radius: 10px; + transition: width 0.5s ease; +} + +.progress-text { + display: flex; + justify-content: space-between; + font-size: 0.9rem; + color: var(--text-secondary); +} + +.goal-details { + display: flex; + gap: 1.5rem; + margin-bottom: 1rem; +} + +.goal-detail-item { + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--text-secondary); + font-size: 0.9rem; +} + +.goal-description { + color: var(--text-secondary); + font-size: 0.9rem; + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid rgba(255, 255, 255, 0.1); +} + +.empty-goals { + grid-column: 1 / -1; + text-align: center; + padding: 4rem 2rem; + color: var(--text-secondary); +} + +.empty-goals i { + margin-bottom: 1rem; + opacity: 0.5; +} + +.empty-goals h3 { + margin-bottom: 0.5rem; + color: var(--text-primary); +} + +/* Modal Styles */ +.modal { + display: none; +/* ===== GLOBAL LOADER ===== */ +.global-loader { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.8); + backdrop-filter: blur(5px); + z-index: 10000; + align-items: center; + justify-content: center; + padding: 2rem; +} + +.modal-content { + background: var(--bg-secondary); + border-radius: 20px; + padding: 2rem; + max-width: 500px; + width: 100%; + max-height: 90vh; + overflow-y: auto; + border: 1px solid rgba(255, 255, 255, 0.1); + animation: slideInDown 0.3s ease; +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 2rem; + padding-bottom: 1rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.modal-header h3 { + font-size: 1.5rem; + color: var(--accent-primary); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.modal-close { + background: transparent; + border: none; + color: var(--text-secondary); + cursor: pointer; + font-size: 1.5rem; + padding: 0.5rem; + border-radius: 5px; + transition: background 0.3s ease; +} + +.modal-close:hover { + background: rgba(255, 255, 255, 0.1); +} + +.goal-form .form-group { + margin-bottom: 1.5rem; +} + +.goal-form label { + display: block; + margin-bottom: 0.5rem; + color: var(--text-primary); + font-weight: 500; +} + +.goal-form input, +.goal-form textarea { + width: 100%; + padding: 0.75rem; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 10px; + color: var(--text-primary); + font-size: 1rem; + font-family: inherit; +} + +.goal-form input:focus, +.goal-form textarea:focus { + outline: none; + border-color: var(--accent-primary); + box-shadow: 0 0 0 3px rgba(100, 255, 218, 0.1); +} + +.modal-actions { + display: flex; + gap: 1rem; + justify-content: flex-end; + margin-top: 2rem; +} + +/* Settings Section */ +.settings-container { + max-width: 900px; + margin: 0 auto; +} + +.settings-section { + margin-bottom: 3rem; +} + +.settings-section h3 { + font-size: 1.8rem; + margin-bottom: 1.5rem; + color: var(--accent-primary); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.settings-card { + background: var(--bg-secondary); + border-radius: 20px; + padding: 2rem; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.setting-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1.5rem 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.setting-item:last-child { + border-bottom: none; +} + +.setting-info { + flex: 1; +} + +.setting-info label { + display: block; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 0.25rem; +} + +.setting-info p { + font-size: 0.9rem; + color: var(--text-secondary); +} + +.setting-input, +.setting-select { + padding: 0.75rem; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 10px; + color: var(--text-primary); + font-size: 1rem; + min-width: 200px; +} + +.setting-input:focus, +.setting-select:focus { + outline: none; + border-color: var(--accent-primary); + box-shadow: 0 0 0 3px rgba(100, 255, 218, 0.1); +} + +.theme-options { + display: flex; + gap: 1rem; +} + +.theme-btn { + padding: 0.75rem 1.5rem; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 10px; + color: var(--text-primary); + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.theme-btn:hover { + background: rgba(255, 255, 255, 0.1); +} + +.theme-btn.active { + background: var(--primary-gradient); + border-color: transparent; +} + +.color-picker { + width: 60px; + height: 40px; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 10px; + cursor: pointer; + background: transparent; +} + +.toggle-switch { + position: relative; + display: inline-block; + width: 60px; + height: 30px; +} + +.toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +.toggle-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.2); + transition: 0.3s; + border-radius: 30px; +} + +.toggle-slider:before { + position: absolute; + content: ""; + height: 22px; + width: 22px; + left: 4px; + bottom: 4px; + background-color: white; + transition: 0.3s; + border-radius: 50%; +} + +.toggle-switch input:checked + .toggle-slider { + background: var(--primary-gradient); +} + +.toggle-switch input:checked + .toggle-slider:before { + transform: translateX(30px); +} + +.btn-danger { + background: linear-gradient(135deg, #ff5722 0%, #f44336 100%); + color: white; + border: none; + padding: 0.75rem 1.5rem; + border-radius: 10px; + cursor: pointer; + font-weight: 600; + transition: transform 0.3s ease, box-shadow 0.3s ease; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.btn-danger:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(255, 87, 34, 0.4); +} + +.about-info { + text-align: center; + color: var(--text-secondary); +} + +.about-info p { + margin-bottom: 1rem; +} + +.about-info strong { + color: var(--accent-primary); + font-size: 1.2rem; +} + +.about-links { + display: flex; + gap: 1rem; + justify-content: center; + margin-top: 1.5rem; +} + +.about-links a { + color: var(--accent-primary); + text-decoration: none; + padding: 0.5rem 1rem; + border: 1px solid var(--accent-primary); + border-radius: 10px; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.about-links a:hover { + background: var(--accent-primary); + color: var(--bg-primary); +} + +/* Footer Links */ +.footer-link { + transition: color 0.3s ease; +} + +.footer-link:hover { + color: var(--accent-primary); +} + +/* Responsive Design for New Sections */ +@media (max-width: 768px) { + .analytics-grid { + grid-template-columns: 1fr; + } + + .goals-grid { + grid-template-columns: 1fr; + } + + .stats-grid { + grid-template-columns: 1fr; + } + + .setting-item { + flex-direction: column; + align-items: flex-start; + gap: 1rem; + } + + .setting-input, + .setting-select { + width: 100%; + min-width: auto; + } + + .section-header h2 { + font-size: 2rem; + } + + .modal-content { + padding: 1.5rem; + } +} background: rgba(15, 15, 35, 0.75); backdrop-filter: blur(6px); display: flex; diff --git a/index.html b/index.html index 4815a708..5225eabf 100644 --- a/index.html +++ b/index.html @@ -24,10 +24,10 @@ ExpenseFlow - Smart Money Management - + - +