tourist partly done
This commit is contained in:
parent
8b3da8ff6e
commit
4100a51194
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ API/bin
|
|||||||
API/obj
|
API/obj
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
|
/rust-backend/.env.example
|
||||||
|
1
Mobile/.gitignore
vendored
1
Mobile/.gitignore
vendored
@ -44,3 +44,4 @@ app.*.map.json
|
|||||||
|
|
||||||
environment.json
|
environment.json
|
||||||
node_modules
|
node_modules
|
||||||
|
.env
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/api.dart' as api;
|
import 'package:mobile/services/api.dart' as api;
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'variables.dart';
|
import 'variables.dart';
|
||||||
@ -104,6 +104,14 @@ class _SideMenuState extends State<SideMenu> {
|
|||||||
Navigator.pushReplacementNamed(context, '/profile');
|
Navigator.pushReplacementNamed(context, '/profile');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
title: const Text('GuideBook'),
|
||||||
|
leading: const Icon(Icons.person),
|
||||||
|
selected: _selectedIndex == 5,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pushReplacementNamed(context, '/tourist-guide-book');
|
||||||
|
},
|
||||||
|
),
|
||||||
const Divider(
|
const Divider(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
thickness: 2,
|
thickness: 2,
|
||||||
|
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:mobile/base/sidemenu.dart';
|
import 'package:mobile/base/sidemenu.dart';
|
||||||
import 'models.dart' as models;
|
import 'models.dart' as models;
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
class CreateReviewPage extends StatefulWidget {
|
class CreateReviewPage extends StatefulWidget {
|
||||||
|
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:mobile/models.dart' as models;
|
import 'package:mobile/models.dart' as models;
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
import 'base/variables.dart';
|
import 'base/variables.dart';
|
||||||
|
|
||||||
class EditProfilePage extends StatefulWidget {
|
class EditProfilePage extends StatefulWidget {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'base/sidemenu.dart'; // Import the base layout widget
|
import 'base/sidemenu.dart'; // Import the base layout widget
|
||||||
import 'models.dart';
|
import 'models.dart';
|
||||||
|
@ -4,7 +4,7 @@ import 'package:mobile/models.dart' as models;
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
import 'base/variables.dart';
|
import 'base/variables.dart';
|
||||||
|
|
||||||
class LoginPage extends StatefulWidget {
|
class LoginPage extends StatefulWidget {
|
||||||
|
@ -8,13 +8,14 @@ import 'package:mobile/createreview.dart';
|
|||||||
import 'package:mobile/favorites.dart';
|
import 'package:mobile/favorites.dart';
|
||||||
import 'package:mobile/register.dart';
|
import 'package:mobile/register.dart';
|
||||||
import 'package:mobile/reviewlist.dart';
|
import 'package:mobile/reviewlist.dart';
|
||||||
|
import 'package:mobile/touristguidebook.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'login.dart';
|
import 'login.dart';
|
||||||
import 'base/sidemenu.dart';
|
import 'base/sidemenu.dart';
|
||||||
import 'profile.dart';
|
import 'profile.dart';
|
||||||
import 'models.dart';
|
import 'models.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
@ -48,6 +49,7 @@ class MyApp extends StatelessWidget {
|
|||||||
'/register': (context) => const RegisterPage(),
|
'/register': (context) => const RegisterPage(),
|
||||||
'/reviews': (context) => const ReviewListPage(),
|
'/reviews': (context) => const ReviewListPage(),
|
||||||
'/create-review': (context) => const CreateReviewPage(),
|
'/create-review': (context) => const CreateReviewPage(),
|
||||||
|
'/tourist-guide-book': (context) => const TouristGuideBookPage(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import 'package:mobile/base/variables.dart';
|
|||||||
import 'package:mobile/models.dart' as models;
|
import 'package:mobile/models.dart' as models;
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'base/sidemenu.dart';
|
import 'base/sidemenu.dart';
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
import 'editprofile.dart';
|
import 'editprofile.dart';
|
||||||
|
|
||||||
class ProfilePage extends StatefulWidget {
|
class ProfilePage extends StatefulWidget {
|
||||||
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:mobile/base/sidemenu.dart';
|
import 'package:mobile/base/sidemenu.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:mobile/base/variables.dart';
|
import 'package:mobile/base/variables.dart';
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
|
|
||||||
class RegisterPage extends StatefulWidget {
|
class RegisterPage extends StatefulWidget {
|
||||||
const RegisterPage({super.key});
|
const RegisterPage({super.key});
|
||||||
|
@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/base/sidemenu.dart';
|
import 'package:mobile/base/sidemenu.dart';
|
||||||
import 'models.dart' as models;
|
import 'models.dart' as models;
|
||||||
import 'api.dart' as api;
|
import 'services/api.dart' as api;
|
||||||
|
|
||||||
class ReviewListPage extends StatefulWidget {
|
class ReviewListPage extends StatefulWidget {
|
||||||
const ReviewListPage({super.key});
|
const ReviewListPage({super.key});
|
||||||
|
@ -193,5 +193,3 @@ void logout() async {
|
|||||||
prefs.remove('refresh-token');
|
prefs.remove('refresh-token');
|
||||||
prefs.remove('id');
|
prefs.remove('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------OPENAI API------------------------------//
|
|
49
Mobile/lib/services/openaiservice.dart
Normal file
49
Mobile/lib/services/openaiservice.dart
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
|
|
||||||
|
class OpenAIService {
|
||||||
|
static Future<Map<String, dynamic>> getGuideBook(String country) async {
|
||||||
|
final apiKey = dotenv.env['OPENAI_API_KEY'];
|
||||||
|
final uri = Uri.parse('https://api.openai.com/v1/chat/completions');
|
||||||
|
|
||||||
|
final requestBody = jsonEncode({
|
||||||
|
"model": "gpt-4o-mini",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "You are a Tourist-guide book that makes a guidebook over a given country and further instructions in the message."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Make a tourist guide book over $country. The topics should be: A little introduction to how the people of the country is like and what to expect from the environment, famous tourist attractions in the country(amusement park always included), Basic words that would be nice to learn in the country's language(should always be from English to the country's language) and transportation. These topics should be in a Json-Object format."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
final response = await http.post(
|
||||||
|
uri,
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer $apiKey',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: requestBody,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
return jsonDecode(response.body);
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
'navn': 'Fejl',
|
||||||
|
'art': 'Ukendt',
|
||||||
|
'type': 'Fejl',
|
||||||
|
'description': 'Fejl ved JSON parsing: $e'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw Exception('Fejl ved hentning af data: ${response.statusCode}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
Mobile/lib/touristguidebook.dart
Normal file
86
Mobile/lib/touristguidebook.dart
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import 'package:dropdown_search/dropdown_search.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mobile/base/sidemenu.dart';
|
||||||
|
import 'package:mobile/models.dart' as models;
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'services/openaiservice.dart' as api;
|
||||||
|
import 'base/variables.dart';
|
||||||
|
|
||||||
|
class TouristGuideBookPage extends StatefulWidget {
|
||||||
|
const TouristGuideBookPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<TouristGuideBookPage> createState() => _TouristGuideBookPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TouristGuideBookPageState extends State<TouristGuideBookPage> {
|
||||||
|
String? _selectedCountry;
|
||||||
|
final List<String> countries = [
|
||||||
|
"Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Argentina",
|
||||||
|
// Add more countries
|
||||||
|
];
|
||||||
|
|
||||||
|
Future<void> getBook() async {
|
||||||
|
if (_selectedCountry != null) {
|
||||||
|
final response = await api.OpenAIService.getGuideBook(_selectedCountry!);
|
||||||
|
print(response); // For debugging to check the response
|
||||||
|
} else {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('Choose a country')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SideMenu(
|
||||||
|
selectedIndex: 5,
|
||||||
|
body: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Select Country'),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
DropdownSearch<String>(
|
||||||
|
items: countries,
|
||||||
|
popupProps: const PopupProps.menu(
|
||||||
|
showSearchBox: true,
|
||||||
|
searchFieldProps: TextFieldProps(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "Search a country",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dropdownDecoratorProps: const DropDownDecoratorProps(
|
||||||
|
dropdownSearchDecoration: InputDecoration(
|
||||||
|
labelText: "Select a country",
|
||||||
|
hintText: "Search a country",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onChanged: (String? country) {
|
||||||
|
setState(() {
|
||||||
|
_selectedCountry = country;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
selectedItem: "Select a country you want a touristbook for",
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: getBook,
|
||||||
|
child: Text('Get Guidebook'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -73,6 +73,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
dropdown_search:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dropdown_search
|
||||||
|
sha256: "55106e8290acaa97ed15bea1fdad82c3cf0c248dd410e651f5a8ac6870f783ab"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.6"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -142,6 +150,14 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_dotenv:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_dotenv
|
||||||
|
sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.1.0"
|
||||||
flutter_image_compress:
|
flutter_image_compress:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -43,6 +43,8 @@ dependencies:
|
|||||||
geolocator: ^13.0.1
|
geolocator: ^13.0.1
|
||||||
image_picker: ^1.1.2
|
image_picker: ^1.1.2
|
||||||
flutter_image_compress: ^2.3.0
|
flutter_image_compress: ^2.3.0
|
||||||
|
flutter_dotenv: ^5.1.0
|
||||||
|
dropdown_search: ^5.0.6
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
JWT_SECRET=DenHerMåAldrigVæreOffentligKunIDetteDemoProjekt
|
|
||||||
AWS_ACCESS_KEY_ID=
|
|
||||||
AWS_SECRET_ACCESS_KEY=
|
|
||||||
AWS_ENDPOINT_URL=
|
|
||||||
AWS_REGION=
|
|
||||||
R2_BUCKET_NAME=
|
|
||||||
R2_BUCKET_URL=
|
|
Loading…
Reference in New Issue
Block a user