Skip to content

Commit

Permalink
Merge pull request #62 from FindMyProfessors/mobile
Browse files Browse the repository at this point in the history
Mobile
  • Loading branch information
LockedThread authored Jul 26, 2024
2 parents ae11181 + d09fce2 commit 4adf193
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 1 deletion.
156 changes: 156 additions & 0 deletions mobile/app/lib/screens/shopping_cart2.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

final storage = new FlutterSecureStorage();

void main() {
runApp(UniversityClassesApp());
}

class UniversityClassesApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'University Classes Shopping Cart',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ShoppingCartPage(),
);
}
}

class ShoppingCartPage extends StatefulWidget {
@override
_ShoppingCartPageState createState() => _ShoppingCartPageState();
}

Future<void> getCart(BuildContext context) async {
print("Loading User SCHOOLS to Dashboard...");
String? JWT = await storage.read(key: 'JWT');
try {
var response = await http.post(
Uri.parse('https://findmyprofessors-api.warrensnipes.dev/users/'+storage+'/cart'),
headers: {
'Content-Type': 'application/json',
'accept': '*/*',
},
);

print("Response status: ${response.statusCode}");
print("Response headers: ${response.headers}");
print("Response body: ${response.body}");

final responseData = json.decode(response.body);

if (response.statusCode == 200) {
print("successfull cart search");
Cart = [];
final List<dynamic> course_cart = responseData['cart_courses'];

for (var professor in course_cart) {
final String course_id = professor['first_name'] + ' ' + professor['last_name'];
final int professorID = professor['id'];
Cart?.add(new Name_ID(professorID, course_id));
}
}
else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(responseData['message']),
),
);
print('Failed to Load Schools: ${response.body[0]}');
}
}
catch (e) {
print('ERROR occurred: $e');
}
}

class _ShoppingCartPageState extends State<ShoppingCartPage> {
final List<String> cart = [
'Math 101',
'History 202',
'Biology 303'
];

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your Classes'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'Classes in Your Cart',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Colors.blue[800]),
),
),
Divider(),
Expanded(
child: ListView.builder(
itemCount: cart.length,
itemBuilder: (context, index) {
final course = cart[index];
return Card(
margin: EdgeInsets.symmetric(vertical: 10, horizontal: 16),
elevation: 3,
child: ListTile(
title: Text(course, style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500)),
trailing: IconButton(
icon: Icon(Icons.remove_circle, color: Colors.red),
onPressed: () {
setState(() {
cart.removeAt(index);
});
},
),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: cart.isNotEmpty
? () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Checkout Successful'),
content: Text('You have registered for ${cart.length} classes.'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
);
},
);
}
: null,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue[700], // background color
foregroundColor: Colors.white, // text color
padding: EdgeInsets.symmetric(horizontal: 50, vertical: 15),
textStyle: TextStyle(fontSize: 18),
),
child: Text('Checkout'),
),
),
],
),
);
}
}
97 changes: 97 additions & 0 deletions mobile/app/test/signup_screen_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:app/screens/signup_screen.dart'; // Adjust the import path according to your project structure


String validatePassword(String password) {
// Regular expressions for different requirements
final RegExp hasUppercase = RegExp(r'(?=.*[A-Z])');
final RegExp hasLowercase = RegExp(r'(?=.*[a-z])');
final RegExp hasDigit = RegExp(r'(?=.*\d)');
final RegExp hasSpecialChar = RegExp(r'(?=.*[@$!%*?&])');

// List to collect missing requirements
List<String> missingRequirements = [];

// Check each requirement and add to the list if missing
if (password.length < 8) {
missingRequirements.add('\n\t\t\t\t\t\tat least 8 characters long');
}
if (password.length >= 50) {
missingRequirements.add('\n\t\t\t\t\t\tat most 50 characters long');
}
if (!hasUppercase.hasMatch(password)) {
missingRequirements.add('\n\t\t\t\t\t\tmust contain an uppercase letter');
}
if (!hasLowercase.hasMatch(password)) {
missingRequirements.add('\n\t\t\t\t\t\tmust contain a lowercase letter');
}
if (!hasDigit.hasMatch(password)) {
missingRequirements.add('\n\t\t\t\t\t\tmust contain a digit');
}
if (!hasSpecialChar.hasMatch(password)) {
missingRequirements.add('\n\t\t\t\t\t\tmust contain a special character');
}

// Return the missing requirements or a success message
if (missingRequirements.isEmpty) {
return '';
} else {
return missingRequirements.join();
}
}
void main() {
group('validatePassword', () {
test('should return an empty string when the password is valid', () {
String password = 'Valid@1234';
String result = validatePassword(password);
expect(result, '');
});

test('should return error message when password is less than 8 characters', () {
String password = 'Va@123';
String result = validatePassword(password);
expect(result, contains('at least 8 characters long'));
});

test('should return error message when password is more than 50 characters', () {
String password = 'V' * 51 + '@1234';
String result = validatePassword(password);
expect(result, contains('at most 50 characters long'));
});

test('should return error message when password does not contain an uppercase letter', () {
String password = 'valid@1234';
String result = validatePassword(password);
expect(result, contains('must contain an uppercase letter'));
});

test('should return error message when password does not contain a lowercase letter', () {
String password = 'VALID@1234';
String result = validatePassword(password);
expect(result, contains('must contain a lowercase letter'));
});

test('should return error message when password does not contain a digit', () {
String password = 'Valid@abcd';
String result = validatePassword(password);
expect(result, contains('must contain a digit'));
});

test('should return error message when password does not contain a special character', () {
String password = 'Valid1234';
String result = validatePassword(password);
expect(result, contains('must contain a special character'));
});

test('should return error messages for multiple requirements', () {
String password = 'val';
String result = validatePassword(password);
expect(result, allOf(
contains('at least 8 characters long'),
contains('must contain an uppercase letter'),
contains('must contain a digit'),
contains('must contain a special character')
));
});
});
}
3 changes: 2 additions & 1 deletion scraper/schools/ucf/ucf.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ func (u *Scraper) Terms() (terms []model.Term) {
currentYear := time.Now().Year() + 1
// TODO: Only add next semester after, determine current semester and next

for i := 0; i < 2; i++ {
const AMOUNT_OF_YEARS = 15
for i := 0; i < AMOUNT_OF_YEARS; i++ {
year := currentYear - i
yearDifference := year - 1963

Expand Down

0 comments on commit 4adf193

Please sign in to comment.