# Creating Your First App

Step-by-step guide to building your first VibesEZ-Laptop app.

## Before You Start

### Prerequisites

You should have:

* [x] JavaScript/TypeScript knowledge
* [x] Basic React understanding (recommended)
* [x] VibesEZ-Laptop installed locally
* [x] Node.js and npm installed
* [x] Text editor (VS Code recommended)

### What You'll Build

A simple **Weather App** that displays mock weather data.

This will teach you:

* App structure
* Registration process
* UI implementation
* Data handling
* Styling

***

## Step 1: Plan Your App

Before coding, define:

**Basic Info:**

```
Name: Weather Widget
ID: weather_app
Description: Display current weather conditions
Version: 1.0.0
```

**Features:**

* Display current temperature
* Show weather condition (sunny, rainy, etc.)
* Update every 5 minutes
* Show city name

**Permissions Needed:**

* Read-only (no wallet/sensitive access)
* No special permissions

**UI Design:**

```
┌──────────────────┐
│ 🌤️ Weather Info  │
├──────────────────┤
│ Los Santos       │
│                  │
│ 72°F Sunny       │
│ Wind: 5 mph      │
│ Humidity: 65%    │
└──────────────────┘
```

***

## Step 2: Set Up Project Structure

### Create Project Directory

```bash
mkdir weather_app
cd weather_app
```

### Initialize Node Project

```bash
npm init -y
npm install react react-dom typescript
npm install -D tailwindcss @types/react vite
```

### Create Folder Structure

```
weather_app/
├── src/
│   ├── App.tsx
│   ├── App.css
│   ├── main.tsx
│   ├── index.html
│   └── vite-env.d.ts
├── package.json
├── tsconfig.json
├── tailwind.config.js
└── vite.config.ts
```

***

## Step 3: Create App Entry

Create `src/App.tsx`:

```typescript
import React, { useState, useEffect } from 'react';
import './App.css';

interface WeatherData {
    city: string;
    temperature: number;
    condition: string;
    humidity: number;
    windSpeed: number;
    icon: string;
}

export const App: React.FC = () => {
    const [weather, setWeather] = useState<WeatherData | null>(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        // Simulate weather API call
        const fetchWeather = () => {
            const mockWeather: WeatherData = {
                city: 'Los Santos',
                temperature: 72,
                condition: 'Sunny',
                humidity: 65,
                windSpeed: 5,
                icon: '🌤️'
            };
            setWeather(mockWeather);
            setLoading(false);
        };

        fetchWeather();
        
        // Update every 5 minutes
        const interval = setInterval(fetchWeather, 300000);
        return () => clearInterval(interval);
    }, []);

    if (loading) {
        return (
            <div className="flex items-center justify-center h-screen">
                <p>Loading weather...</p>
            </div>
        );
    }

    return (
        <div className="p-6 bg-gradient-to-br from-blue-400 to-blue-600 rounded-lg text-white">
            <h2 className="text-2xl font-bold mb-4">
                {weather?.icon} Weather
            </h2>
            
            <div className="space-y-3">
                <div>
                    <p className="text-sm opacity-80">Location</p>
                    <p className="text-xl font-semibold">{weather?.city}</p>
                </div>
                
                <div>
                    <p className="text-sm opacity-80">Condition</p>
                    <p className="text-3xl font-bold">
                        {weather?.temperature}°F
                    </p>
                    <p className="text-lg">{weather?.condition}</p>
                </div>
                
                <div className="grid grid-cols-2 gap-4 text-sm">
                    <div>
                        <p className="opacity-80">Humidity</p>
                        <p className="font-semibold">{weather?.humidity}%</p>
                    </div>
                    <div>
                        <p className="opacity-80">Wind Speed</p>
                        <p className="font-semibold">{weather?.windSpeed} mph</p>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default App;
```

***

## Step 4: Register Your App

Create `src/main.tsx`:

```typescript
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';

// Register app with VibesEZ-Laptop
const registerApp = () => {
    // @ts-ignore - VibesEZ export
    if (window.exports?.['VibesEZ-Laptop']) {
        exports['VibesEZ-Laptop'].RegisterApp({
            id: 'weather_app',
            label: 'Weather',
            event: 'weather_app:open'
        });
    }
};

registerApp();

ReactDOM.createRoot(document.getElementById('root')!).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
);
```

***

## Step 5: Build & Package

### Create `vite.config.ts`:

```typescript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
    plugins: [react()],
    build: {
        outDir: 'dist',
        rollupOptions: {
            output: {
                entryFileNames: `app.js`,
                chunkFileNames: `chunks/[name].js`,
                assetFileNames: `assets/[name].[ext]`
            }
        }
    }
})
```

### Build the App

```bash
npm run build
```

***

## Step 6: Deploy to VibesEZ-Laptop

### Copy to Resources

```bash
# Copy built app to your server
cp -r dist/ /path/to/server/resources/[apps]/weather_app/
```

### Verify Structure

```
server/resources/[apps]/weather_app/
├── app.js
├── app.css
└── index.html
```

***

## Step 7: Test Your App

### Start Server

```bash
# In your FXServer
```

### Launch App

1. Open laptop in-game
2. Should see "Weather" app on home screen
3. Click to open from home screen

**Expected Result:** Weather information displays correctly

***

## Step 8: Enhance Your App

### Add Real Weather API

Replace mock data with real API:

```typescript
const fetchWeather = async () => {
    try {
        // Example: Call your server for weather data
        const response = await fetch('https://api.weather.com/weather');
        const data = await response.json();
        setWeather(data);
    } catch (error) {
        console.error('Weather fetch failed:', error);
    }
    setLoading(false);
};
```

### Add User Interaction

```typescript
const [activeTab, setActiveTab] = useState<'now' | 'forecast'>('now');

return (
    <div>
        <div className="flex gap-2 mb-4">
            <button 
                onClick={() => setActiveTab('now')}
                className={activeTab === 'now' ? 'bg-white text-blue-600' : ''}
            >
                Now
            </button>
            <button 
                onClick={() => setActiveTab('forecast')}
                className={activeTab === 'forecast' ? 'bg-white text-blue-600' : ''}
            >
                Forecast
            </button>
        </div>
        {activeTab === 'now' && <CurrentWeather />}
        {activeTab === 'forecast' && <Forecast />}
    </div>
);
```

***

## Common Issues & Solutions

### App Won't Install

**Problem:** App appears in store but can't install

**Solutions:**

1. Check console for errors
2. Verify file structure
3. Ensure JavaScript builds correctly
4. Check file permissions

### Styling Not Loading

**Problem:** App displays but no CSS styling

**Solutions:**

1. Verify CSS import in main file
2. Check Tailwind configuration
3. Rebuild CSS
4. Check browser console for CSS errors

### App Won't Register

**Problem:** App doesn't appear in laptop

**Solutions:**

1. Verify registration code runs
2. Check export naming
3. Ensure VibesEZ-Laptop loaded first
4. Review console for registration errors

***

## Next Steps

1. **Learn More APIs:** [API Reference](/vibesez/docs/laptop/for-developers/api-reference.md)
2. **See More Examples:** [Examples & Templates](/vibesez/docs/laptop/for-developers/examples.md)
3. **Best Practices:** [Best Practices](/vibesez/docs/laptop/for-developers/best-practices.md)
4. **Publish Your App:** Contact developers or use app store submission

***

**Congratulations!** You've created your first VibesEZ-Laptop app!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vibesez.gitbook.io/vibesez/docs/laptop/for-developers/creating-apps.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
