FlutterとFlask Pythonで作る！簡単従業員管理アプリ



## FlutterとPythonでアプリを作ろう
こんにちは！今回は、FlutterとFlask Pythonを使って、シンプルだけど便利な従業員管理アプリを作っていきます。モバイルアプリとバックエンドの両方を扱うので、フルスタック開発の良い練習になりますよ。それでは、始めましょう！

### 第1章: プロジェクトのセットアップ

まずは、必要なツールをインストールしましょう。FlutterとFlaskの環境を整えます。

```bash
# Flutterのインストール
flutter pub get

# Flaskのインストール
pip install flask flask-sqlalchemy
```

これで準備完了！次は、プロジェクトの構造を作っていきます。

### 第2章: Flaskバックエンドの作成

バックエンドから始めましょう。`app.py`ファイルを作成し、以下のコードを書きます。

```python
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///employees.db'
db = SQLAlchemy(app)

class Employee(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    position = db.Column(db.String(100), nullable=False)

@app.route('/employees', methods=['GET', 'POST'])
def handle_employees():
    if request.method == 'POST':
        data = request.json
        new_employee = Employee(name=data['name'], position=data['position'])
        db.session.add(new_employee)
        db.session.commit()
        return jsonify({"message": "Employee added successfully"}), 201
    
    employees = Employee.query.all()
    return jsonify([{"id": e.id, "name": e.name, "position": e.position} for e in employees])

if __name__ == '__main__':
    db.create_all()
    app.run(debug=True)
```

`employee`テーブルは以下のSQLで作れます

```sql
CREATE TABLE employee (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(100) NOT NULL,
    position VARCHAR(100) NOT NULL
);
```

これで、従業員の追加と一覧表示ができるAPIができました！

### 第3章: Flutterプロジェクトの作成

次は、Flutterでモバイルアプリを作ります。新しいプロジェクトを作成しましょう。

```bash
flutter create employee_management_app
cd employee_management_app
```

### 第4章: Flutterで従業員一覧画面の作成

`lib/main.dart`ファイルを編集して、従業員一覧画面を作ります。

```dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '従業員管理アプリ',
      home: EmployeeList(),
    );
  }
}

class EmployeeList extends StatefulWidget {
  @override
  _EmployeeListState createState() => _EmployeeListState();
}

class _EmployeeListState extends State<EmployeeList> {
  List<dynamic> employees = [];

  @override
  void initState() {
    super.initState();
    fetchEmployees();
  }

  fetchEmployees() async {
    final response = await http.get(Uri.parse('http://localhost:5000/employees'));
    if (response.statusCode == 200) {
      setState(() {
        employees = json.decode(response.body);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('従業員一覧')),
      body: ListView.builder(
        itemCount: employees.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(employees[index]['name']),
            subtitle: Text(employees[index]['position']),
          );
        },
      ),
    );
  }
}
```

これで、従業員一覧が表示されるアプリの基本部分ができました！

### 第5章: 従業員追加機能の実装

次は、新しい従業員を追加する機能を実装しましょう。

```dart
// _EmployeeListStateクラスに以下のメソッドを追加

void _addEmployee() {
  showDialog(
    context: context,
    builder: (BuildContext context) {
      String name = '';
      String position = '';
      return AlertDialog(
        title: Text('新しい従業員を追加'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            TextField(
              decoration: InputDecoration(labelText: '名前'),
              onChanged: (value) {
                name = value;
              },
            ),
            TextField(
              decoration: InputDecoration(labelText: '役職'),
              onChanged: (value) {
                position = value;
              },
            ),
          ],
        ),
        actions: <Widget>[
          TextButton(
            child: Text('キャンセル'),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
          TextButton(
            child: Text('追加'),
            onPressed: () {
              _submitEmployee(name, position);
              Navigator.of(context).pop();
            },
          ),
        ],
      );
    },
  );
}

void _submitEmployee(String name, String position) async {
  final response = await http.post(
    Uri.parse('http://localhost:5000/employees'),
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(<String, String>{
      'name': name,
      'position': position,
    }),
  );

  if (response.statusCode == 201) {
    fetchEmployees();  // 一覧を更新
  }
}

// buildメソッド内のScaffoldにfloatingActionButtonを追加
floatingActionButton: FloatingActionButton(
  onPressed: _addEmployee,
  tooltip: '従業員を追加',
  child: Icon(Icons.add),
),
```

これで、新しい従業員を追加する機能が実装できました！

### 第6章: エラーハンドリングとUI改善

アプリをより使いやすくするために、エラーハンドリングとUIの改善を行いましょう。

```dart
// _EmployeeListStateクラスに以下のメソッドを追加

void _showSnackBar(String message) {
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text(message)),
  );
}

// _submitEmployeeメソッドを以下のように修正

void _submitEmployee(String name, String position) async {
  if (name.isEmpty || position.isEmpty) {
    _showSnackBar('名前と役職を入力してください');
    return;
  }

  try {
    final response = await http.post(
      Uri.parse('http://localhost:5000/employees'),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
      body: jsonEncode(<String, String>{
        'name': name,
        'position': position,
      }),
    );

    if (response.statusCode == 201) {
      fetchEmployees();
      _showSnackBar('従業員を追加しました');
    } else {
      _showSnackBar('エラーが発生しました');
    }
  } catch (e) {
    _showSnackBar('ネットワークエラーが発生しました');
  }
}
```

これで、エラーメッセージが表示されるようになり、ユーザー体験が向上しました！

### 第7章: アプリのテストと配布

最後に、アプリのテストと配布の準備をしましょう。

1. ユニットテストの作成
2. ウィジェットテストの作成
3. インテグレーションテストの実行
4. ビルドとリリース準備

```bash
# テストの実行
flutter test

# リリースビルドの作成（Android用）
flutter build apk

# リリースビルドの作成（iOS用）
flutter build ios
```

これで、従業員管理アプリの開発が完了しました！FlutterとFlask Pythonを使って、シンプルながら機能的なアプリを作ることができましたね。

このアプリをベースに、さらに機能を追加したり、デザインを改善したりして、自分だけのオリジナルアプリを作ってみてください。頑張ってください！