はじめに
こんにちは!今回は、FlutterとFlaskを使用して、ユーザーが1時間または2時間のパートタイム求人に応募でき、管理者が新しい求人を投稿できるアプリを作成する方法をご紹介します。
APIはローカルホストのポート8000で動作すると仮定します。
Flutterプロジェクトのセットアップ
まず、新しいFlutterプロジェクトを作成しましょう。
flutter create part_time_job_app
cd part_time_job_app
APIとの通信
FlutterアプリからFlask APIと通信するために、http
パッケージを使用します。pubspec.yaml
に以下を追加してください:
dependencies:
http: ^0.13.3
求人一覧の表示
FlaskAPIから求人一覧を取得し、表示する機能を実装します。
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: 'Part-Time Job App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: JobListScreen(),
);
}
}
class Job {
final int id;
final String title;
final String description;
final int duration; // Duration in hours
Job({required this.id, required this.title, required this.description, required this.duration});
factory Job.fromJson(Map<String, dynamic> json) {
return Job(
id: json['id'],
title: json['title'],
description: json['description'],
duration: json['duration'],
);
}
}
class JobListScreen extends StatefulWidget {
@override
_JobListScreenState createState() => _JobListScreenState();
}
class _JobListScreenState extends State<JobListScreen> {
late Future<List<Job>> futureJobs;
@override
void initState() {
super.initState();
futureJobs = fetchJobs();
}
Future<List<Job>> fetchJobs() async {
final response = await http.get(Uri.parse('http://localhost:8000/jobs'));
if (response.statusCode == 200) {
List<dynamic> jobsJson = json.decode(response.body);
return jobsJson.map((job) => Job.fromJson(job)).toList();
} else {
throw Exception('Failed to load jobs');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Part-Time Jobs'),
),
body: FutureBuilder<List<Job>>(
future: futureJobs,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text('No jobs available'));
} else {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
Job job = snapshot.data![index];
return ListTile(
title: Text(job.title),
subtitle: Text('${job.description} - ${job.duration} hours'),
onTap: () => applyForJob(job.id),
);
},
);
}
},
),
);
}
Future<void> applyForJob(int jobId) async {
final response = await http.post(
Uri.parse('http://localhost:8000/apply'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, int>{
'job_id': jobId,
}),
);
if (response.statusCode == 200) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Applied successfully')));
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to apply')));
}
}
}
管理者用求人投稿機能
管理者が新しい求人を投稿できる機能を実装します。
class AdminScreen extends StatelessWidget {
final TextEditingController titleController = TextEditingController();
final TextEditingController descriptionController = TextEditingController();
final TextEditingController durationController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Post New Job'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: titleController,
decoration: InputDecoration(labelText: 'Job Title'),
),
TextField(
controller: descriptionController,
decoration: InputDecoration(labelText: 'Job Description'),
),
TextField(
controller: durationController,
decoration: InputDecoration(labelText: 'Duration (hours)'),
keyboardType: TextInputType.number,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => postNewJob(
titleController.text,
descriptionController.text,
int.parse(durationController.text),
),
child: Text('Post Job'),
),
],
),
),
);
}
Future<void> postNewJob(String title, String description, int duration) async {
final response = await http.post(
Uri.parse('http://localhost:8000/jobs'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, dynamic>{
'title': title,
'description': description,
'duration': duration,
}),
);
if (response.statusCode == 201) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Job posted successfully')));
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to post job')));
}
}
}
Flask APIの実装
最後に、Flask APIを実装します。
from flask import Flask, request, jsonify
app = Flask(__name__)
jobs = []
applications = []
@app.route('/jobs', methods=['GET', 'POST'])
def manage_jobs():
if request.method == 'POST':
job = request.get_json()
job['id'] = len(jobs) + 1
jobs.append(job)
return jsonify(job), 201
else:
return jsonify(jobs)
@app.route('/apply', methods=['POST'])
def apply_job():
application = request.get_json()
applications.append(application)
return '', 200
if __name__ == '__main__':
app.run(port=8000)
まとめ
以上が、FlutterとFlaskを使用して1時間または2時間のパートタイム求人に応募できるアプリを作成する基本的な実装例です。
実際のアプリケーションでは、ユーザー認証、エラーハンドリング、UIの改善など、さらに多くの機能を追加する必要があります。