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
Code editor (VS Code recommended)
Initial Setup
git clone https://github.com/B2DevUK/b2-sleeknotify.git
cd b2-sleeknotify
Development Server
Start the development server with hot reload:
Building for Production
Create a production build:
UI Development
Tech Stack
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
Add style option in config.lua
:
Config = {
Style = 'custom', -- 'minimal', 'advanced', or 'custom'
...
}
const CustomStyle = ({ notification }) => (
<div className="your-custom-classes">
{/* Your custom notification layout */}
</div>
);
{style === 'custom' ?
<CustomStyle notification={notification} /> :
style === 'minimal' ?
<MinimalStyle notification={notification} /> :
<AdvancedStyle notification={notification} />}
Production Build Process
1. Development and Testing
Test changes using the development server.
2. Production 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:
Best Practices
Performance
Use React.memo for pure components
Implement proper cleanup in useEffect
Optimize re-renders with proper state management
Styling
Use Tailwind utility classes
Maintain consistent color schemes
Follow the established naming conventions
Testing
Test all notification types
Check animation performance
Test with different screen resolutions
Error Handling
Implement proper error boundaries
Handle missing or invalid data gracefully
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