Commit 9c420da7 authored by Joao Victor G. Cosentino's avatar Joao Victor G. Cosentino
Browse files

Merge branch 'develop' into 'main'

Sprint 1 frontend

See merge request !35
parents 0f939ee7 db1dfbe4
Showing with 1046 additions and 98 deletions
+1046 -98
......@@ -31,6 +31,7 @@ migrate_working_dir/
.pub-cache/
.pub/
/build/
pubspec.lock
# Symbolication related
app.*.symbols
......
{
"project_info": {
"project_number": "1047671029557",
"project_id": "sow-good",
"storage_bucket": "sow-good.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:1047671029557:android:221f8bb56475cf3386967c",
"android_client_info": {
"package_name": "com.example.sow_good"
}
},
"oauth_client": [
{
"client_id": "1047671029557-j66ij3o8u51ckef13r95dr7i2nsgub6o.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVVOQWjcbgsC5lH8aRSujdwkjRPMSlfJs"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "1047671029557-j66ij3o8u51ckef13r95dr7i2nsgub6o.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "1047671029557-rva0miq0in56p432vtjmg0kbrk71m5qj.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.example.sowGood"
}
}
]
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
assets/images/logo_sow_good.png

9.99 KB

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>1047671029557-rva0miq0in56p432vtjmg0kbrk71m5qj.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.1047671029557-rva0miq0in56p432vtjmg0kbrk71m5qj</string>
<key>API_KEY</key>
<string>AIzaSyCwfLKFEVDmyno1LgfHFjfMPVnCLkRyo1M</string>
<key>GCM_SENDER_ID</key>
<string>1047671029557</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.example.sowGood</string>
<key>PROJECT_ID</key>
<string>sow-good</string>
<key>STORAGE_BUCKET</key>
<string>sow-good.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:1047671029557:ios:f064c763a792045686967c</string>
</dict>
</plist>
\ No newline at end of file
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:1047671029557:ios:f064c763a792045686967c",
"FIREBASE_PROJECT_ID": "sow-good",
"GCM_SENDER_ID": "1047671029557"
}
\ No newline at end of file
arb-dir: lib/l10n
template-arb-file: intl_en.arb
output-localization-file: app_localizations.dart
\ No newline at end of file
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyC2xI-AsRhcxS5NbNMirtYmReHhpfWuj4E',
appId: '1:1047671029557:web:71a2860a70f1bcbb86967c',
messagingSenderId: '1047671029557',
projectId: 'sow-good',
authDomain: 'sow-good.firebaseapp.com',
storageBucket: 'sow-good.appspot.com',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyAVVOQWjcbgsC5lH8aRSujdwkjRPMSlfJs',
appId: '1:1047671029557:android:221f8bb56475cf3386967c',
messagingSenderId: '1047671029557',
projectId: 'sow-good',
storageBucket: 'sow-good.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyCwfLKFEVDmyno1LgfHFjfMPVnCLkRyo1M',
appId: '1:1047671029557:ios:f064c763a792045686967c',
messagingSenderId: '1047671029557',
projectId: 'sow-good',
storageBucket: 'sow-good.appspot.com',
iosClientId: '1047671029557-rva0miq0in56p432vtjmg0kbrk71m5qj.apps.googleusercontent.com',
iosBundleId: 'com.example.sowGood',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyCwfLKFEVDmyno1LgfHFjfMPVnCLkRyo1M',
appId: '1:1047671029557:ios:f064c763a792045686967c',
messagingSenderId: '1047671029557',
projectId: 'sow-good',
storageBucket: 'sow-good.appspot.com',
iosClientId: '1047671029557-rva0miq0in56p432vtjmg0kbrk71m5qj.apps.googleusercontent.com',
iosBundleId: 'com.example.sowGood',
);
}
lib/images/FotoPlaceholderCrianca.png

13.8 KB

{
"helloWorld": " Hello World!",
"login": "login"
}
\ No newline at end of file
import 'package:flutter/material.dart';
void main() {
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:sow_good/views/screens/login_page.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
debugShowCheckedModeBanner: false,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: const LoginPage(),
);
}
}
class HealthInsurance {
final String? image;
final String? name;
const HealthInsurance({this.image, this.name});
}
class Patient {
Patient({
this.password,
this.email,
this.name,
this.birthDate,
this.cpf,
this.sex,
this.medicalData,
this.guardians,
});
String? password;
String? email;
String? name;
String? birthDate;
String? cpf;
String? sex;
MedicalData? medicalData;
List<String>? guardians;
factory Patient.fromJson(Map<String, dynamic> json) => Patient(
password: json['password'],
email: json['email'],
name: json['name'],
birthDate: json['birth_date'],
cpf: json['cpf'],
sex: json['sex'],
medicalData: MedicalData.fromJson(json['medical_data']),
guardians: List<String>.from(json['guardians'].map((x) => x)),
);
Map<String, dynamic> toJson() => {
'password': password,
'email': email,
'name': name,
'birth_date': birthDate,
'cpf': cpf,
'sex': sex,
'medical_data': medicalData!.toJson(),
'guardians': List<dynamic>.from(guardians!.map((String x) => x)),
};
}
class MedicalData {
MedicalData({
this.alergies,
this.medications,
this.observations,
});
String? alergies;
String? medications;
String? observations;
factory MedicalData.fromJson(Map<String, dynamic> json) => MedicalData(
alergies: json['alergies'] ?? '',
medications: json['medications'] ?? '',
observations: json['observations'] ?? '',
);
Map<String, dynamic> toJson() => {
'alergies': alergies,
'medications': medications,
'observations': observations,
};
}
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:sow_good/models/patient.dart';
class PatientService {
static const String apiUrl = 'http://ec2-18-119-119-203.us-east-2.compute.amazonaws.com:80/api/v1/patients';
Future<Map<String, dynamic>?> getPatient(String uidAuth) async {
final response = await http.get(Uri.parse('$apiUrl/$uidAuth'));
if (response.statusCode == 200) {
final jsonData = jsonDecode(response.body);
return jsonData;
} else if (response.statusCode == 404) {
return null;
} else {
throw Exception('Failed to get patient data');
}
}
Future<String> postPatients(Patient patient) async {
print(jsonEncode(patient.toJson()));
final http.Response response = await http
.post(Uri.parse(apiUrl), body: jsonEncode(patient.toJson()), headers: {
'Content-Type': 'application/json',
});
return response.body;
}
}
class TextValidator {
static String? validateRequired(String? value) {
if (value == null || value.isEmpty) {
return 'Campo obrigatório';
}
return null;
}
static String? validateNumberWithSize(
String value, num size, String message) {
// ignore: prefer_interpolation_to_compose_strings
String pattern = r'\d{' + size.toString() + '}';
RegExp regExp = RegExp(pattern);
if (!regExp.hasMatch(value) || value.length > size || value.length < size) {
return message;
}
return null;
}
static String? validateEmail(String value) {
RegExp regExp = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+");
if (!regExp.hasMatch(value)) {
return 'E-mail inválido';
}
return null;
}
static String? validatePassword(String value) {
String pattern = r'(?=.*[0-9a-zA-Z]).{6,}';
RegExp regExp = RegExp(pattern);
if (!regExp.hasMatch(value)) {
return 'Senha inválida, precisa conter no mínimo 6 caracteres';
}
return null;
}
}
import 'package:flutter/material.dart';
class CustomColors {
static const Color medicPrimary = Color(0xff5C93AA);
static const Color patientPrimary = Color(0xffFF5A8D);
static const Color blue = Color(0xff0077B5);
static const Color black = Color(0xff000000);
static const Color white = Color(0xffFFFFFF);
static const Color graySubtitle = Color(0xff545454);
static const Color grayDivider = Color(0xff6C6C6C);
static const Color background = Color(0xffffffff);
static const Color error = Color(0xFFC62828);
}
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class CustomTextStyles {
static TextStyle placeholder = GoogleFonts.roboto(fontSize: 16);
static TextStyle title = GoogleFonts.roboto(fontSize: 28);
}
class CustomTextStylesBuilder {
Color? _color;
double? _height;
double? _fontSize;
TextDecoration? _decoration;
TextStyle title() {
TextStyle style = GoogleFonts.roboto(
fontSize: _fontSize,
color: _color,
height: _height,
decoration: _decoration,
);
return style;
}
TextStyle placeholder() {
TextStyle style = GoogleFonts.roboto(
fontSize: _fontSize,
color: _color,
height: _height,
decoration: _decoration,
);
return style;
}
CustomTextStylesBuilder withColor(Color color) {
_color = color;
return this;
}
CustomTextStylesBuilder withSize(double size) {
_fontSize = size;
return this;
}
}
import 'package:flutter/material.dart';
import 'package:sow_good/views/design_tokens/custom_colors.dart';
import 'package:sow_good/views/design_tokens/custom_text_styles.dart';
import 'package:sow_good/views/widgets/sg_text_field.dart';
import 'package:sow_good/views/widgets/button.dart';
import 'package:sow_good/views/screens/register_patient_account.dart';
import 'package:sow_good/validators/text_validators.dart';
import 'package:sow_good/services/patient_service.dart';
import 'package:flutter/gestures.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:sow_good/views/screens/profile_patient.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
String _userError = '';
Map<String, dynamic> _patient = {};
double displayWidth(BuildContext context) {
return MediaQuery.of(context).size.width;
}
void createAccount() {
Navigator.push(
context,
MaterialPageRoute<RegisterPatientAccount>(
builder: (BuildContext context) => const RegisterPatientAccount()),
);
}
void signIn() async {
if (_formKey.currentState!.validate()) {
setState(() {
_userError = '';
});
try {
UserCredential userCredential =
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
setState(() {
_emailController.text = '';
_passwordController.text = '';
});
_patient = await PatientService().getPatient(userCredential.user!.uid) ?? {};
if (_patient.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute<ProfilePatient>(
builder: (BuildContext context) => const ProfilePatient()),
);
} else {
setState(() {
_userError = 'Apenas para pacientes';
});
}
} on FirebaseAuthException catch (e) {
if (e.code == 'invalid-email') {
setState(() {
_userError = 'Email invalido';
});
}
if (e.code == 'user-not-found') {
setState(() {
_userError = 'Usuário não encontrado';
});
}
if (e.code == 'wrong-password') {
setState(() {
_userError = 'Sua senha esta incorreta';
});
}
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Stack(
children: <Widget>[
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
height: MediaQuery.of(context).size.height * 0.3,
color: CustomColors.patientPrimary,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
SizedBox(
height: 50,
),
Text('Sow Good',
style: TextStyle(
fontFamily: 'Roboto',
fontWeight: FontWeight.bold,
fontSize: 32,
color: Colors.white)),
SizedBox(
height: 28,
),
Text('Cuidado e segurança para sua família',
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 14,
color: CustomColors.white,
fontWeight: FontWeight.normal)),
SizedBox(
height: 41,
),
],
),
),
),
Positioned(
top: MediaQuery.of(context).size.height * 0.3,
left: 0,
right: 0,
bottom: 0,
child: Container(
alignment: Alignment.center,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20))),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
top: 39, left: 61, bottom: 45),
child: Container(
alignment: Alignment.centerLeft,
child: const Text('Login',
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 28,
color: CustomColors.patientPrimary,
fontWeight: FontWeight.bold)),
),
),
Form(
key: _formKey,
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 15),
child: SGTextField(
controller: _emailController,
validator: TextValidator.validateRequired,
placeholder: 'E-mail',
icon: Icons.mail_outlined,
type: FieldType.text,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 44),
child: SGTextField(
controller: _passwordController,
validator: TextValidator.validateRequired,
placeholder: '***********',
icon: Icons.lock_outline,
isPassword: true,
type: FieldType.text),
),
if (_userError != '')
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Text(
_userError,
style: const TextStyle(color: Colors.red),
),
),
]),
),
Padding(
padding: const EdgeInsets.only(bottom: 34),
child: VariableTextPinkButton(
text: 'Entrar', onPressed: signIn),
),
RichText(
text: TextSpan(
text: 'Não possui uma conta? ',
style: CustomTextStylesBuilder()
.withColor(CustomColors.black)
.withSize(14)
.placeholder(),
children: <TextSpan>[
TextSpan(
text: 'Cadastre-se',
style: CustomTextStylesBuilder()
.withSize(14)
.withColor(CustomColors.patientPrimary)
.placeholder(),
recognizer: TapGestureRecognizer()
..onTap = () {
createAccount();
},
),
],
),
)
],
),
),
),
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:sow_good/views/design_tokens/custom_colors.dart';
import 'package:sow_good/views/widgets/button.dart';
import 'package:sow_good/views/widgets/sg_app_bar.dart';
import 'package:sow_good/views/widgets/sg_componente_medico.dart';
import 'package:sow_good/views/widgets/sg_health_insurance.dart';
import 'package:sow_good/models/health_insurance.dart';
class ProfileDoctor extends StatefulWidget {
const ProfileDoctor({super.key});
@override
State<ProfileDoctor> createState() => _ProfileDoctorState();
}
class _ProfileDoctorState extends State<ProfileDoctor> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
List<HealthInsurance> healthInsurances = [
const HealthInsurance(
name: 'Bradesco',
image:
'data:image/png;base64,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'),
const HealthInsurance(
name: 'Bradesco',
image:
'data:image/png;base64,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'),
const HealthInsurance(
name: 'Bradesco',
image:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAA3lBMVEUAm1n///8Am1j///4AkkoAlEoCmVn5//8AlVIAmVa/6dun18L///0AnFf//f8AmFRrwZyz3crd8umh38yJ38js/PqU2ML3//3J8+zY9OtYwp0Ap3BwuJMrqHMAj0XT9vFasoNDtIYAmE8Ak1MApWm57d4/vY+n1sIntYiI1bqr6NHR7uG35tTh+/TO7OIApWAAlFoOuIJPv58zvpub4dGB1LZezKl8yrBrxKZawZkYqHZwwpqZ4sYAjTqB2L1VuZOAx6Sd1rhYtIFlyq6/4807sn5TsH7C8eBgs4lVw5Mh5uEDAAAH5UlEQVR4nO2ZDVfjNhaGLVmWpWBFk6EhgexAsQOEIaEwU4ZJ+kHp7pT2//+hXkmWnXQWKJnjzjm77wMcbMuS7qsrX13ZSQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8H+GDH/ya9vRHdzoRBujJTfma9vSDbpSwmFJ5Ne2ZQv483dUp2c7g8FgZ6bMP6LweZM2kVIc1sjGQlnGa0o/WdtwKXZZzbnayuK/A5e8sfOlAynt28uLwNLyeO3jRX1x/rRE6jjJa4HpwnbnQ66nl2TSJXGu5Iued2mG0Qd70QdSfBOv5eZJhcbIN/HWlMnuFEr7O2N9309PvEQh+YAPWZp+prBgRVDIn7SaJ+sKu4s0hptvWW0nKXxBP9LwZM2HwV88WfPh0wrpAfluxPo0GmmRLq7sl6h4GvttNKmXvWQgn1OYPqOQCsXc+89Hmv9BhYS+Oh3M53O3WvCnA++ThjyaFNVT8p9RGA+1VVYnnIe1SZYic2t+pa8oAnAfj3lctLSmW9smpLaWzv9iIqfbrNq4sa2gFF3mnSqUxkqyyxprK7LcZnoyezebKCW1F6jIZldulSG1VTguyS5D1k2v381WMnOKpdSHcnVKVcuMYocMY2Ykt0JPr2fL97OpUVXi9Icyzm2WXL9/f51ktlsfquPxUeB7JcVkd+GLFjdhXVIf6sKjWyUTsRuOx0ezyqqDsb91tHdVSinVah6qHn2s6vlc0gDJZW9RdzfsHdjK8qCec7Ga+8U2n6+q8vcOfWh/qOMq28+yGx9X8oJiy4Vf4SmnqVebgeD88HU47rODbLUfW2aLqZbqR9+iX4XeqjBTjRGv6v6Lvi9ZHFRxucs++gq+9Cbr0odRYZ/t/7RLlqSu1z5p3BXaK6wZiCQ5fB3Plm9GNCakvnAjMBbqkjWLLMVd4c1UsuduSd0Y5UUo+rkKPhR33gI/fDm7+a3LWfqqFsguliSuKGIZW1EMyNYUchkV9tlp60HH3TnL86I5HUlOj2CpLupEhf6lsezGJS1St4axftrPD7pXSOwPC9ZYUvhce1Nh48Oc9YLL6qy1GDcCgp4lBSopzmP5Gilb0fTX4oa1A1L0WWNmdwrz0P2aJemJeERhv76jn8bRKPp5UTS1czZQXOpV9CAFk/O92p9FnzRQHF7ESe2vpo3cTn3I2Ml8cNKO7FH5iMKczFrM57vDxod9Nt5tq6b9E3qGxV6c8qOVyIS6icVTbeSkHc/F7ezdvOm1U4Uj4zbz3zU1RonciDTtLE3ZXka3lhdRETt155NhUXvthDor4yrBPgi3uIt4TutO+UsjaVGKqjxs5Hf7HJKGRKvlswppdh7Q6pioWSzMp9plB+dh5pFHLdfHsYxNLUUW7VNcd8OPQqu9RuHS7Xl0h+vhpkJqXTeB+3EfMnZgXbS8qtth+YQa59RU/TyNlbQxPPbHhxnNUvHTfa3wNSlsZvTQdJC1qUcVSsmNbraET83SA7fRMDY8S2nwYaJ/WFOY/dyI2N/fv6DfUTw/5GLcFNLSSVHp1+0UJppzWgHqHbDwlyijyL5h8XkpNxWSfP53FDofOncndduF92Gi/xWLx8qIdiJukLJhxkXT0Gtv1rY+pKReD2Mc3glVSaH4PgbqEYW8jhTqtuamQKdQtwr9w7+9Qq7tuPZhWlfliRRNPjKkbUBXCinsPMK+0K0Jiy9TSJlTL87SfCprv06a5fWt6GyWavWhPs7z3iYTq0Wv6SRzqbjZViHNyLMmX5gLsop2OW3rbEeYrhTK8q7ppnTrrI+n9C9zeWmbSIym7oOB3lqhtKexap9dXle0X7++bHpm14p3pTDR0yaM3xy6Dx+0RyYoX5V8fT08r0rJ1R/bKiSfNaGGwmc+Ho9Ym/Iu3AvmjhRyKdqh/FgJ696NeIVaJ7xq0ooiPRWHVXK0vUJ1G5sq3DvBYj27vnXbuK5mKW+TI9r3D/59enoc+EQLoJVtGXv4T6/dSr1YIa3KC9Zs+tYgjx75xrqapbTujovPd0/EtdtZ95qNh38b+wUKpfpUC/or+RvbrUI9zf+rREpSE3W3tlej/KPJ4l6uMEmq43xj5xftn7jkubtI43r+FBO1lpQduWeDntI1k4rh8fYKjdRq9cA+m6YP04r7N58dKpRq0uSfrcJdp0HK6aK9OFxt+Z4mYsXywTee1u/NWO9O1G/8TLmeeZNk2yjMzYbCyuhW4TuXeUve2Ogzb7seSxP32UNnvmfms7XQ9/BV6W2qpg+xYH8i2t2T2OYrnpaVmnwcnCxGLB8NTwavpmvNyOmO42xnZ+mmLS1W9zuBW0Ue/bQTTgfXtKBVf5y5Y7riFV3Zm3Dn/X251hQRVDiUmFLPtGTlo9HiZH4/M9lV4tVLdTcf5vlwvsw0jzXPftnuWzM3FLyVKmlNKpXKSlmnqAHKMxwiWEk9r59bn4fQmZMklS8TIuzEtAm30rn/aqO1qM+tbTogP2ZWlcq9Kafq2if/rh9a9+lqWamSQo/NatTLP3QHq90f9x9IZPxQEr4+GClNvMddiJ8ntbMhWBn2JJp+4ttcGb53yPi//sASzxMZ32u7wyR07huVctNDVCH8urvCgGylEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdMifrzikX9ISW2UAAAAASUVORK5CYII='),
];
void openMaterials() async {}
double displayHeight(BuildContext context) {
return MediaQuery.of(context).size.height;
}
double displayWidth(BuildContext context) {
return MediaQuery.of(context).size.width;
}
void nextScreen() {
if (_formKey.currentState!.validate()) {}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: sgAppBar('Meu Médico', context),
backgroundColor: CustomColors.background,
body: SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 25),
child: Column(
children: <Widget>[
const SGcomponenteMedico(
crm: '12345',
endereco: 'Av.Ipiranga, 264/ Ap.1020',
especialidade: 'Nutrologista',
nome: 'Dr. Rafael da Silva',
rqe: 'RQE 12345',
),
const Divider(
thickness: 2,
color: CustomColors.patientPrimary,
),
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 7),
child: Container(
alignment: Alignment.topLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 13, top: 20),
child: Text(
'Sobre mim:',
style: TextStyle(
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.left,
),
),
Padding(
padding: EdgeInsets.only(bottom: 16),
child: Text(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque egestas urna nibh, ut fringilla mi hendrerit id. Donec posuere libero at feugiat tincidunt. Vestibulum a blandit sapien. Integer tempus quam dui, ut dignissim nisl eleifend sed. In vitae est eu purus gravida tincidunt eu quis augue. Mauris hendrerit scelerisque dignissim.',
style:
TextStyle(color: CustomColors.graySubtitle),
),
),
],
),
),
),
const Divider(
thickness: 0.5,
color: CustomColors.graySubtitle,
),
],
),
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 7),
child: Container(
alignment: Alignment.topLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Padding(
padding: EdgeInsets.only(bottom: 13, top: 20),
child: Text(
'Convênios:',
style: TextStyle(
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.left,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: SGHealthInsurance(
healthInsurances: healthInsurances),
),
],
),
),
),
const Divider(
thickness: 0.5,
color: CustomColors.graySubtitle,
),
],
),
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 7),
child: Container(
alignment: Alignment.topLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Padding(
padding: EdgeInsets.only(bottom: 13, top: 20),
child: Text(
'Materiais:',
style: TextStyle(
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.left,
),
),
Center(
child: Padding(
padding: const EdgeInsets.only(bottom: 16),
child: VariableTextPinkButton(
onPressed: nextScreen,
text: 'Google Drive',
),
),
),
],
),
),
),
],
),
],
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:sow_good/views/design_tokens/custom_colors.dart';
import 'package:sow_good/views/screens/profile_doctor.dart';
import 'package:sow_good/views/widgets/patient_profile_card.dart';
import 'package:sow_good/views/widgets/sg_text_button.dart';
class ProfilePatient extends StatefulWidget {
const ProfilePatient({super.key});
@override
State<ProfilePatient> createState() => _ProfilePatientState();
}
class _ProfilePatientState extends State<ProfilePatient> {
void nextScreen() {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => const ProfileDoctor(),
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CustomColors.white,
appBar: PreferredSize(
preferredSize: const Size.fromHeight(400),
child: PatientCard(
name: 'Daniel Gus',
age: 5,
parents: 'Tania',
birthDate: '20/01/2018',
profilePictureUrl:
'https://cdn.pixabay.com/photo/2015/03/17/01/57/kid-677080_1280.jpg')),
body: SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 0.2),
child: Column(
children: [
SGTextButton(
onPressed: () {},
title: 'Chat',
subTitle: 'Fale com nossos especialistas',
icon: Icons.chat_outlined,
),
SGTextButton(
onPressed: () {},
title: 'Diário',
subTitle: 'Evolução do patiente',
icon: Icons.menu_book_outlined,
),
SGTextButton(
onPressed: () {},
title: 'Dados médicos',
subTitle: 'Evolução do patiente',
icon: Icons.list_alt_outlined,
),
SGTextButton(
onPressed: () => nextScreen(),
title: 'Meu médico',
subTitle: 'Fale com os nossos especialistas',
icon: Icons.person_outlined,
),
SGTextButton(
onPressed: () {},
title: 'Configurações',
subTitle: 'Ajustes do aplicativo',
icon: Icons.settings_outlined,
),
],
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:sow_good/models/patient.dart';
import 'package:sow_good/validators/text_validators.dart';
import 'package:sow_good/views/design_tokens/custom_colors.dart';
import 'package:sow_good/views/design_tokens/custom_text_styles.dart';
import 'package:sow_good/views/screens/register_patient_data.dart';
import 'package:sow_good/views/widgets/button.dart';
import 'package:sow_good/views/widgets/sg_text_field.dart';
class RegisterPatientAccount extends StatefulWidget {
const RegisterPatientAccount({super.key});
@override
State<RegisterPatientAccount> createState() => _RegisterPatientAccountState();
}
class _RegisterPatientAccountState extends State<RegisterPatientAccount> {
final TextEditingController _emailControl = TextEditingController();
final TextEditingController _passwordControl = TextEditingController();
final TextEditingController _passwordConfirmControl = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late Patient patient;
String? _emailValidator(String? email) {
String? error = TextValidator.validateRequired(email);
return error ?? TextValidator.validateEmail(email!);
}
String? _passwordValidator(String? password) {
String? error = TextValidator.validateRequired(password);
return error ?? TextValidator.validatePassword(password!);
}
String? _passwordConfirmValidator(String? passwordConfirmation) {
String? error = TextValidator.validateRequired(passwordConfirmation);
return error ??
(passwordConfirmation == _passwordControl.text
? null
: 'As senhas não coincidem');
}
double displayHeight(BuildContext context) {
return MediaQuery.of(context).size.height;
}
double displayWidth(BuildContext context) {
return MediaQuery.of(context).size.width;
}
void nextScreen() {
if (_formKey.currentState!.validate()) {
patient =
Patient(password: _passwordControl.text, email: _emailControl.text);
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
RegisterPatientData(patient: patient),
));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: TextButton.icon(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back_ios,
size: 14,
color: CustomColors.black,
),
label: Text(
'Voltar',
style: CustomTextStylesBuilder()
.withSize(14)
.withColor(CustomColors.black)
.placeholder(),
),
),
leadingWidth: 80,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(3),
child: Container(
color: CustomColors.patientPrimary,
height: 3,
width: double.infinity,
)),
centerTitle: true,
backgroundColor: CustomColors.white,
title: Text(
'Cadastro',
style: CustomTextStylesBuilder()
.withColor(CustomColors.black)
.withSize(26)
.title(),
),
),
body: Center(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(
vertical: displayHeight(context) * 0.1,
horizontal: 20,
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Container(
alignment: Alignment.topLeft,
child: Text(
'Informações da conta',
style:
CustomTextStylesBuilder().withSize(30).placeholder(),
),
),
),
SizedBox(
height: displayHeight(context) * 0.55,
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 15),
child: SGTextField(
controller: _emailControl,
validator: _emailValidator,
placeholder: 'E-mail',
icon: Icons.email_outlined,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 15),
child: SGTextField(
controller: _passwordControl,
validator: _passwordValidator,
placeholder: 'Senha',
icon: Icons.lock_outline,
isPassword: true,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 15),
child: SGTextField(
controller: _passwordConfirmControl,
validator: _passwordConfirmValidator,
placeholder: 'Confirmar senha',
icon: Icons.lock_outline,
isPassword: true,
),
),
],
),
),
),
),
VariableTextPinkButton(
onPressed: () => nextScreen(),
text: 'Continuar',
),
],
),
),
),
),
);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment