WIP googleLoginBranch #1
@ -6,6 +6,7 @@ plugins {
|
||||
id("kotlin-android")
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id("dev.flutter.flutter-gradle-plugin")
|
||||
id("org.jetbrains.kotlin.android") version "2.1.20"
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
@ -4,6 +4,9 @@ allprojects {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.android") version "2.1.20" apply false
|
||||
}
|
||||
|
||||
val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
|
||||
rootProject.layout.buildDirectory.value(newBuildDir)
|
||||
@ -18,4 +21,4 @@ subprojects {
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
}
|
||||
@ -20,9 +20,12 @@ plugins {
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
id("com.android.application") version "8.7.0" apply false
|
||||
// START: FlutterFire Configuration
|
||||
id("com.google.gms.google-services") version("4.3.15") apply false
|
||||
// END: FlutterFire Configuration
|
||||
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
|
||||
// START: FlutterFire Configuration
|
||||
id("com.google.gms.google-services") version("4.4.2") apply false
|
||||
// END: FlutterFire Configuration
|
||||
//id("org.jetbrains.kotlin.android") version "1.8.22" apply false
|
||||
//id("org.jetbrains.kotlin.android") version "2.1.20" apply false
|
||||
}
|
||||
|
||||
include(":app")
|
||||
|
||||
4
devtools_options.yaml
Normal file
4
devtools_options.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
description: This file stores settings for Dart & Flutter DevTools.
|
||||
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||
extensions:
|
||||
- provider: true
|
||||
@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../services/googleAuthService.dart';
|
||||
|
||||
class ProfilePage extends StatelessWidget {
|
||||
const ProfilePage({super.key});
|
||||
|
||||
@ -15,6 +17,15 @@ class ProfilePage extends StatelessWidget {
|
||||
'Profil',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.logout, color: Colors.white),
|
||||
tooltip: 'Logga ut',
|
||||
onPressed: () async {
|
||||
await GoogleAuthService.logout(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Center(
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../services/googleAuthService.dart';
|
||||
|
||||
class ProfilePageAdmin extends StatelessWidget {
|
||||
const ProfilePageAdmin({super.key});
|
||||
|
||||
@ -15,6 +17,15 @@ class ProfilePageAdmin extends StatelessWidget {
|
||||
'Profil',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.logout, color: Colors.white),
|
||||
tooltip: 'Logga ut',
|
||||
onPressed: () async {
|
||||
await GoogleAuthService.logout(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Center(
|
||||
|
||||
@ -6,6 +6,8 @@ import 'package:insparkspokalen_ui/models/activityModel.dart';
|
||||
|
||||
|
||||
class AdminCalendarPage extends StatefulWidget {
|
||||
const AdminCalendarPage({super.key});
|
||||
|
||||
@override
|
||||
State<AdminCalendarPage> createState() => AdminCalendarPageState();
|
||||
}
|
||||
@ -36,8 +38,8 @@ class AdminCalendarPageState extends State<AdminCalendarPage> {
|
||||
|
||||
void _showDialogCalendar() {
|
||||
print("Dialogen för kalendern öppnas!");
|
||||
final _titleController = TextEditingController();
|
||||
final _placeController = TextEditingController();
|
||||
final titleController = TextEditingController();
|
||||
final placeController = TextEditingController();
|
||||
_slutTidController.clear();
|
||||
_beskrivningController.clear();
|
||||
valdDatumTid = DateTime.now();
|
||||
@ -58,11 +60,11 @@ class AdminCalendarPageState extends State<AdminCalendarPage> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: _titleController,
|
||||
controller: titleController,
|
||||
decoration: const InputDecoration(labelText: 'Titel'),
|
||||
),
|
||||
TextField(
|
||||
controller: _placeController,
|
||||
controller: placeController,
|
||||
decoration: const InputDecoration(labelText: 'Plats'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@ -95,8 +97,8 @@ class AdminCalendarPageState extends State<AdminCalendarPage> {
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
final titel = _titleController.text;
|
||||
final plats = _placeController.text;
|
||||
final titel = titleController.text;
|
||||
final plats = placeController.text;
|
||||
final slutTid = _slutTidController.text.isNotEmpty ? _slutTidController.text : null;
|
||||
final beskrivning = _beskrivningController.text.isNotEmpty ? _beskrivningController.text : null;
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@ import 'package:insparkspokalen_ui/services/activityService.dart';
|
||||
import 'package:insparkspokalen_ui/models/activityModel.dart';
|
||||
|
||||
class Calendar extends StatefulWidget {
|
||||
const Calendar({super.key});
|
||||
|
||||
@override
|
||||
State<Calendar> createState() => _CalendarState();
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:insparkspokalen_ui/models/postModel.dart';
|
||||
import 'package:insparkspokalen_ui/models/teamModel.dart';
|
||||
import 'package:insparkspokalen_ui/feed/adminHomeScreen/main_page_for_admin.dart';
|
||||
|
||||
class AdminInfoBlock extends StatefulWidget {
|
||||
final TeamModel group;
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:insparkspokalen_ui/services/teamService.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'dart:io';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:insparkspokalen_ui/models/teamModel.dart';
|
||||
import 'package:insparkspokalen_ui/models/postModel.dart';
|
||||
import 'package:insparkspokalen_ui/feed/adminHomeScreen/admin_info_block.dart';
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:insparkspokalen_ui/models/teamModel.dart';
|
||||
import 'package:insparkspokalen_ui/feed/usersHomeScreen/info_smallpage.dart';
|
||||
|
||||
//Fixa så denna är rätt, kommer ej vara main
|
||||
class InfoSmallpage extends StatefulWidget {
|
||||
|
||||
@ -12,6 +12,7 @@ class BaseScaffold extends StatelessWidget {
|
||||
final Widget body;
|
||||
final String role; // USER el ADMIN
|
||||
|
||||
|
||||
const BaseScaffold({
|
||||
super.key,
|
||||
required this.title,
|
||||
@ -19,6 +20,7 @@ class BaseScaffold extends StatelessWidget {
|
||||
required this.onTap,
|
||||
required this.body,
|
||||
required this.role, //USER el ADMIN
|
||||
|
||||
});
|
||||
|
||||
@override
|
||||
|
||||
@ -3,7 +3,6 @@ import 'package:insparkspokalen_ui/layout/baseScaffold.dart';
|
||||
import 'package:insparkspokalen_ui/calendar/calendar.dart';
|
||||
import 'package:insparkspokalen_ui/leaderboard/leaderboard.dart';
|
||||
import 'package:insparkspokalen_ui/teams/teamPage.dart';
|
||||
import 'package:insparkspokalen_ui/feed/feedPage.dart';
|
||||
import 'package:insparkspokalen_ui/feed/usersHomeScreen/main_page_for_info.dart';
|
||||
|
||||
class UserHomePage extends StatefulWidget {
|
||||
|
||||
@ -5,7 +5,7 @@ import 'package:insparkspokalen_ui/models/teamModel.dart';
|
||||
import 'package:insparkspokalen_ui/services/teamService.dart';
|
||||
|
||||
class Leaderboard extends StatefulWidget {
|
||||
const Leaderboard({Key? key}) : super(key: key);
|
||||
const Leaderboard({super.key});
|
||||
|
||||
@override
|
||||
State<Leaderboard> createState() => _LeaderboardState();
|
||||
@ -114,7 +114,7 @@ class _TopplistaBody extends StatelessWidget {
|
||||
group: entry.value,
|
||||
place: entry.key + 1,
|
||||
))
|
||||
.toList(),
|
||||
,
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
);
|
||||
@ -125,7 +125,7 @@ class GruppKort extends StatelessWidget {
|
||||
final TeamModel group;
|
||||
final int place;
|
||||
|
||||
const GruppKort.GroupCard({required this.group, required this.place});
|
||||
const GruppKort.GroupCard({super.key, required this.group, required this.place});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@ -3,9 +3,10 @@ import 'package:provider/provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:insparkspokalen_ui/models/teamModel.dart';
|
||||
import 'package:insparkspokalen_ui/services/teamService.dart';
|
||||
import 'package:insparkspokalen_ui/services/googleAuthService.dart';
|
||||
|
||||
class LeaderboardAdmin extends StatefulWidget {
|
||||
const LeaderboardAdmin({Key? key}) : super(key: key);
|
||||
const LeaderboardAdmin({super.key});
|
||||
|
||||
@override
|
||||
State<LeaderboardAdmin> createState() => _LeaderboardState();
|
||||
@ -112,7 +113,7 @@ class _TopplistaBody extends StatelessWidget {
|
||||
group: entry.value,
|
||||
place: entry.key + 1,
|
||||
))
|
||||
.toList(),
|
||||
,
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
);
|
||||
@ -123,7 +124,7 @@ class GruppKort extends StatefulWidget {
|
||||
final TeamModel group;
|
||||
final int place;
|
||||
|
||||
const GruppKort.GroupCard({required this.group, required this.place});
|
||||
const GruppKort.GroupCard({super.key, required this.group, required this.place});
|
||||
|
||||
@override
|
||||
State<GruppKort> createState() => _GruppKortState();
|
||||
@ -226,13 +227,25 @@ Future<void> _updateScore(int scoreChange) async {
|
||||
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add, color: Color(0xFFDAA520)),
|
||||
onPressed: () => _updateScore(1),
|
||||
onPressed: () async {
|
||||
if (!GoogleAuthService.isLoggedIn()) {
|
||||
await GoogleAuthService.signInWithGoogle(context);
|
||||
if (!GoogleAuthService.isLoggedIn()) return; // user cancelled or login failed
|
||||
}
|
||||
_updateScore(1);
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
||||
IconButton(
|
||||
icon: const Icon(Icons.remove, color: Color(0xFFDAA520)),
|
||||
onPressed: () => _updateScore(-1),
|
||||
onPressed: () async {
|
||||
if (!GoogleAuthService.isLoggedIn()) {
|
||||
await GoogleAuthService.signInWithGoogle(context);
|
||||
if (!GoogleAuthService.isLoggedIn()) return; // user cancelled or login failed
|
||||
}
|
||||
_updateScore(1);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:insparkspokalen_ui/login/loginPage.dart';
|
||||
import 'package:insparkspokalen_ui/services/authService.dart';
|
||||
import 'package:insparkspokalen_ui/layout/adminHomePage.dart';
|
||||
import 'package:insparkspokalen_ui/services/googleAuthService.dart';
|
||||
import 'package:insparkspokalen_ui/layout/userHomePage.dart';
|
||||
import 'package:sign_button/sign_button.dart';
|
||||
|
||||
class StartPage extends StatelessWidget {
|
||||
const StartPage({super.key});
|
||||
@ -16,14 +15,13 @@ class StartPage extends StatelessWidget {
|
||||
'Insparkspokalen',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFFFEDF00),
|
||||
color: Colors.yellow,
|
||||
fontSize: 40,
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
backgroundColor: const Color.fromARGB(255, 42, 41, 41),
|
||||
elevation: 0,
|
||||
iconTheme: const IconThemeData(color: Colors.white),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(20),
|
||||
@ -37,72 +35,36 @@ class StartPage extends StatelessWidget {
|
||||
height: 250,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Logga in med Google
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.black,
|
||||
minimumSize: const Size (250, 45),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
icon: SvgPicture.asset(
|
||||
'assets/icons/googleLogo.svg',
|
||||
height: 24,
|
||||
),
|
||||
label: const Text('Logga in med Google'),
|
||||
onPressed: () async {
|
||||
try {
|
||||
await AuthService().signInWithGoogle();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Inloggning lyckades!')),
|
||||
);
|
||||
Navigator.pushReplacement(
|
||||
const SizedBox(height: 60),
|
||||
const SizedBox(height: 30),
|
||||
SignInButton(
|
||||
buttonType: ButtonType.google,
|
||||
buttonSize: ButtonSize.large,
|
||||
onPressed: () => GoogleAuthService.signInWithGoogle(context),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => const AdminHomePage()),
|
||||
MaterialPageRoute(builder: (context) => const UserHomePage()),
|
||||
);
|
||||
} catch (_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Inloggning misslyckades.')),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Logga in som gäst
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const LogInPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFFFEDF00),
|
||||
foregroundColor: Colors.black,
|
||||
minimumSize: const Size (250, 45),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.yellow,
|
||||
foregroundColor: const Color.fromARGB(255, 42, 41, 41),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 34, vertical: 22),
|
||||
),
|
||||
child: const Text('Continue as guest'),
|
||||
),
|
||||
child: const Text('Fortsätt som gäst'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'userModel.g.dart';
|
||||
@ -6,9 +7,9 @@ part 'userModel.g.dart';
|
||||
class UserModel {
|
||||
final String email;
|
||||
final String name;
|
||||
final String role; //USER or ADMIN
|
||||
|
||||
UserModel(this.email, this.name, this.role);
|
||||
final String profilePicture; // URL string
|
||||
// final String role;
|
||||
UserModel(this.email, this.name, this.profilePicture);
|
||||
|
||||
factory UserModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$UserModelFromJson(json);
|
||||
|
||||
@ -9,11 +9,11 @@ part of 'userModel.dart';
|
||||
UserModel _$UserModelFromJson(Map<String, dynamic> json) => UserModel(
|
||||
json['email'] as String,
|
||||
json['name'] as String,
|
||||
json['role'] as String,
|
||||
json['profilePicture'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$UserModelToJson(UserModel instance) => <String, dynamic>{
|
||||
'email': instance.email,
|
||||
'name': instance.name,
|
||||
'role': instance.role,
|
||||
'profilePicture': instance.profilePicture,
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:insparkspokalen_ui/services/googleAuthService.dart';
|
||||
import 'package:insparkspokalen_ui/models/activityModel.dart';
|
||||
|
||||
class ActivityService {
|
||||
@ -8,6 +9,7 @@ class ActivityService {
|
||||
|
||||
// Hämtar alla aktiviteter
|
||||
Future<List<ActivityModel>> fetchActivities() async {
|
||||
|
||||
try {
|
||||
final response = await http.get(Uri.parse('$baseUrl/all'));
|
||||
|
||||
@ -33,6 +35,8 @@ class ActivityService {
|
||||
|
||||
// Skapa en ny aktivitet med post
|
||||
Future<void> createActivity(ActivityModel activity) async {
|
||||
|
||||
|
||||
try {
|
||||
final response = await http.post(
|
||||
Uri.parse('$baseUrl/add'),
|
||||
@ -51,4 +55,6 @@ class ActivityService {
|
||||
}
|
||||
|
||||
//Ta bort en aktivitet
|
||||
|
||||
|
||||
}
|
||||
|
||||
79
lib/services/googleAuthService.dart
Normal file
79
lib/services/googleAuthService.dart
Normal file
@ -0,0 +1,79 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
import 'package:insparkspokalen_ui/login/startPage.dart';
|
||||
// import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../layout/userHomePage.dart';
|
||||
import 'userService.dart';
|
||||
/*
|
||||
|
||||
För att kräva login gör såhär:
|
||||
Lägg till detta paket i klassen ->
|
||||
import 'package:insparkspokalen_ui/services/googleAuthService.dart';
|
||||
|
||||
Sedan lägg till följande för alla knappar som kräver att användaren är inloggad ->
|
||||
onPressed:() async {
|
||||
final isAuthenticated = await GoogleAuthService.ensureLoggedIn(context);
|
||||
if (!isAuthenticated) return;
|
||||
},
|
||||
|
||||
Kör appen med detta kommando då vår konsol endast släpper in redirects från port 8080 via webben för tillfället
|
||||
flutter run -d chrome --web-port=8080
|
||||
*/
|
||||
class GoogleAuthService {
|
||||
static final GoogleSignIn _googleSignIn = GoogleSignIn(
|
||||
clientId: '278095802777-40qt28sou07o3qb58pcoccl0eolas3k0.apps.googleusercontent.com', //web
|
||||
// clientId: '278095802777-8tj05ph2nbb8117abl1k4nlnq4ukd7ao.apps.googleusercontent.com', //android
|
||||
scopes: <String>['email', 'profile'],
|
||||
);
|
||||
|
||||
// todo review this after final login solution is done
|
||||
static String? accessToken;
|
||||
|
||||
static Future<void> signInWithGoogle(BuildContext context) async {
|
||||
try {
|
||||
await _googleSignIn.signOut();
|
||||
final account = await _googleSignIn.signIn();
|
||||
if (account == null) return;
|
||||
|
||||
final auth = await account.authentication;
|
||||
accessToken = auth.accessToken;
|
||||
|
||||
if (accessToken == null) {
|
||||
print("Missing ID token.");
|
||||
return;
|
||||
}
|
||||
// Create user model
|
||||
await UserService.createOrFetchUser(account);
|
||||
|
||||
print("Signed in as ${account.email}, ID Token: $accessToken, name: ${account.displayName}");
|
||||
|
||||
//Continue to app home
|
||||
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const UserHomePage()));
|
||||
} catch (e) {
|
||||
print("Google Sign-In failed: $e");
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> logout(BuildContext context) async {
|
||||
await _googleSignIn.signOut();
|
||||
|
||||
// Clear cache when user logs out removed for now something went wrong with loading the cache
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.remove('user');
|
||||
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => const StartPage()), // Import StartPage
|
||||
(route) => false,
|
||||
);
|
||||
accessToken = null;
|
||||
}
|
||||
|
||||
static Future<bool> ensureLoggedIn(BuildContext context) async {
|
||||
if (!isLoggedIn()) {
|
||||
await signInWithGoogle(context);
|
||||
}
|
||||
return isLoggedIn();
|
||||
}
|
||||
static bool isLoggedIn() => accessToken != null;
|
||||
}
|
||||
@ -37,9 +37,9 @@ class TeamService {
|
||||
|
||||
//Ta bort grupp
|
||||
Future<bool> removeTeam(int teamId, String teamName) async {
|
||||
final adminToken = 'secret123'; // Admin-token, hårdkodad i backend
|
||||
|
||||
final url = Uri.parse(
|
||||
'$baseUrl/remove/team/$teamId?adminToken=${Uri.encodeQueryComponent(adminToken)}',
|
||||
'$baseUrl/remove/team/$teamId',
|
||||
);
|
||||
|
||||
final response = await http.get(url);
|
||||
@ -50,9 +50,14 @@ class TeamService {
|
||||
|
||||
// Funktion för att lägga till poäng
|
||||
Future<bool> updateScore(int teamId, int scoreChange) async {
|
||||
|
||||
|
||||
final url = Uri.parse('$baseUrl/change/$teamId/$scoreChange');
|
||||
|
||||
final response = await http.get(url);
|
||||
|
||||
return response.statusCode == 200;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'package:insparkspokalen_ui/models/userModel.dart';
|
||||
// import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class UserService {
|
||||
final String baseUrl = 'https://group-10-15.pvt.dsv.su.se';
|
||||
//final String baseUrl = 'http://localhost:8080';
|
||||
|
||||
Future<List<UserModel>> showUsers() async {
|
||||
final endpoint = Uri.parse('$baseUrl/all/');
|
||||
final endpoint = Uri.parse('$baseUrl/user/');
|
||||
//final endpoint = Uri.parse('$baseUrl/all');
|
||||
|
||||
try {
|
||||
@ -22,4 +24,47 @@ class UserService {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> createOrFetchUser(GoogleSignInAccount account) async {
|
||||
final service = UserService();
|
||||
final email = account.email;
|
||||
|
||||
try {
|
||||
final getUserEndpoint = Uri.parse('${service.baseUrl}/user/getuser?email=$email');
|
||||
final getUserResponse = await http.get(getUserEndpoint);
|
||||
|
||||
UserModel user;
|
||||
|
||||
if (getUserResponse.statusCode == 200 && getUserResponse.body.isNotEmpty) {
|
||||
user = UserModel.fromJson(jsonDecode(getUserResponse.body));
|
||||
print("User fetched: ${user.toJson()}");
|
||||
} else {
|
||||
user = UserModel(
|
||||
email,
|
||||
account.displayName ?? 'Unknown',
|
||||
account.photoUrl ?? '',
|
||||
);
|
||||
|
||||
final createUserEndpoint = Uri.parse('${service.baseUrl}/user/createuser');
|
||||
final createUserResponse = await http.post(
|
||||
createUserEndpoint,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(user.toJson()),
|
||||
);
|
||||
|
||||
if (!(createUserResponse.statusCode == 200 || createUserResponse.statusCode == 201)) {
|
||||
throw Exception("Failed to create user");
|
||||
}
|
||||
|
||||
print("User created: ${user.toJson()}");
|
||||
}
|
||||
|
||||
// // Cache user
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// prefs.setString('user', jsonEncode(user.toJson()));
|
||||
} catch (e) {
|
||||
print("UserService error: $e");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:insparkspokalen_ui/models/teamModel.dart';
|
||||
import 'package:insparkspokalen_ui/services/googleAuthService.dart';
|
||||
|
||||
class TeamCard extends StatelessWidget {
|
||||
final TeamModel group;
|
||||
@ -31,7 +32,11 @@ class TeamCard extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: onJoin,
|
||||
onPressed:() async {
|
||||
final isAuthenticated = await GoogleAuthService.ensureLoggedIn(context);
|
||||
if (!isAuthenticated) return;
|
||||
onJoin();
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.grey[300],
|
||||
foregroundColor: Colors.black,
|
||||
|
||||
@ -4,6 +4,7 @@ import 'createTeamsButton.dart';
|
||||
import 'showTeams.dart';
|
||||
import 'package:insparkspokalen_ui/services/teamService.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:insparkspokalen_ui/services/googleAuthService.dart';
|
||||
|
||||
class TeamPage extends StatefulWidget {
|
||||
const TeamPage({super.key});
|
||||
@ -77,7 +78,12 @@ class TeamPageState extends State<TeamPage> {
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _openDialog,
|
||||
onPressed: () async {
|
||||
final isAuthenticated = await GoogleAuthService.ensureLoggedIn(context);
|
||||
if (!isAuthenticated) return;
|
||||
|
||||
_openDialog(); // or your next step
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.grey,
|
||||
shape: RoundedRectangleBorder(
|
||||
|
||||
@ -44,7 +44,16 @@ dependencies:
|
||||
firebase_storage: ^12.4.5
|
||||
uuid: ^4.5.1
|
||||
|
||||
# Required for signin with google
|
||||
google_sign_in: ^6.3.0
|
||||
# Required for the google button on startPage.dart
|
||||
sign_button: ^2.0.6
|
||||
|
||||
# cache test
|
||||
# shared_preferences: ^2.2.2
|
||||
|
||||
# google_sign_in_all_platforms: ^1.0.0
|
||||
url_launcher: ^6.0.20
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user