Development

Development Guide

Project Structure

b2-sleeknotify/
├── client/
│   ├── main.lua
│   └── config.lua
├── server/
│   └── main.lua
├── ui/
│   ├── src/
│   │   ├── components/
│   │   │   └── NotificationSystem.jsx
│   │   ├── App.jsx
│   │   └── main.jsx
│   ├── public/
│   ├── package.json
│   ├── vite.config.js
│   └── tailwind.config.js
└── fxmanifest.lua

Development Environment Setup

Prerequisites

  • Node.js 18 or higher

  • npm or yarn

  • Git

  • Code editor (VS Code recommended)

Initial Setup

  1. Clone the repository:

git clone https://github.com/B2DevUK/b2-sleeknotify.git
cd b2-sleeknotify
  1. Install UI dependencies:

cd ui
npm install

Development Server

Start the development server with hot reload:

npm run dev

Building for Production

Create a production build:

npm run build

UI Development

Tech Stack

  • React 18

  • Tailwind CSS

  • Vite

  • Lucide Icons

Key Components

NotificationSystem.jsx

The main component handling notifications. Key sections:

// State Management
const [notifications, setNotifications] = useState([]);
const [style, setStyle] = useState('minimal');

// NUI Message Handler
React.useEffect(() => {
  const handleMessage = (event) => {
    const { action, notification, id, config } = event.data;

    if (action === 'setStyle') {
      setStyle(config.style);
    } else if (action === 'addNotification') {
      setNotifications(prev => [...prev, {
        ...notification,
        time: 'Just now'
      }]);
    } else if (action === 'removeNotification') {
      setNotifications(prev => 
        prev.filter(notif => notif.id !== id)
      );
    }
  };

  window.addEventListener('message', handleMessage);
  return () => window.removeEventListener('message', handleMessage);
}, []);

Styling Guide

Tailwind Configuration

The project uses Tailwind CSS for styling. Customize tailwind.config.js:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      // Custom colors matching notification types
      colors: {
        success: {
          400: '#34D399', // Emerald
        },
        error: {
          400: '#F87171', // Red
        },
        info: {
          400: '#60A5FA', // Blue
        },
        warning: {
          400: '#FBBF24', // Amber
        }
      }
    }
  },
  plugins: []
}

Color System

We use a consistent color system across notification types:

// Color utilities for different styles
const getMinimalColors = (type) => ({
  success: 'border-l-emerald-400 text-emerald-400',
  error: 'border-l-red-400 text-red-400',
  info: 'border-l-blue-400 text-blue-400',
  warning: 'border-l-amber-400 text-amber-400'
}[type]);

const getAdvancedColors = (type) => ({
  success: 'from-emerald-400/10 to-emerald-400/5 border-emerald-400/20',
  error: 'from-red-400/10 to-red-400/5 border-red-400/20',
  info: 'from-blue-400/10 to-blue-400/5 border-blue-400/20',
  warning: 'from-amber-400/10 to-amber-400/5 border-amber-400/20'
}[type]);

NUI Communication

Sending Messages to Lua

const removeNotification = (id) => {
  fetch(`https://${GetParentResourceName()}/notificationClosed`, {
    method: 'POST',
    body: JSON.stringify({ id })
  });
};

Receiving Messages from Lua

window.addEventListener('message', (event) => {
  const { action, notification, id, config } = event.data;
  // Handle different actions
});

Building Custom Styles

Creating a New Style

  1. Add style option in config.lua:

Config = {
    Style = 'custom', -- 'minimal', 'advanced', or 'custom'
    ...
}
  1. Create style component:

const CustomStyle = ({ notification }) => (
  <div className="your-custom-classes">
    {/* Your custom notification layout */}
  </div>
);
  1. Add to style renderer:

{style === 'custom' ? 
  <CustomStyle notification={notification} /> :
  style === 'minimal' ? 
    <MinimalStyle notification={notification} /> :
    <AdvancedStyle notification={notification} />}

Production Build Process

1. Development and Testing

cd ui
npm run dev

Test changes using the development server.

2. Production Build

npm run build

This creates optimized files in ui/dist/.

3. Testing the Production Build

  • Copy the contents of ui/dist/ to your FiveM server

  • Ensure paths in fxmanifest.lua match your build output

4. Debugging

Enable development tools in FiveM:

SetNuiFocus(true, true)

Use browser dev tools to:

  • Monitor network requests

  • Debug React components

  • Check for console errors

Best Practices

  1. Performance

    • Use React.memo for pure components

    • Implement proper cleanup in useEffect

    • Optimize re-renders with proper state management

  2. Styling

    • Use Tailwind utility classes

    • Maintain consistent color schemes

    • Follow the established naming conventions

  3. Testing

    • Test all notification types

    • Verify position handling

    • Check animation performance

    • Test with different screen resolutions

  4. Error Handling

    • Implement proper error boundaries

    • Handle missing or invalid data gracefully

    • Provide fallback styles

Common Issues and Solutions

Issue: Notifications not showing

// Check NUI focus and debugging
window.invokeNative('getNuiFocus', (focused) => {
  console.log('NUI Focus:', focused);
});

Issue: Styles not applying correctly

// Verify style application
console.log('Current style:', style);
console.log('Notification data:', notification);

Last updated