Skip to content

Commit

Permalink
Merge pull request #18 from felipecastrosales/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
felipecastrosales authored Aug 24, 2024
2 parents 6981669 + 49d36b4 commit 265053b
Show file tree
Hide file tree
Showing 91 changed files with 1,585 additions and 620 deletions.
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# You can get these keys from https://www.google.com/recaptcha/admin
RECAPTCHA_PUBLIC_KEY=your_public_key
RECAPTCHA_SECRET_KEY=your_secret_key

# Create your api key from AWS SES / API Gateway:
# - https://aws.amazon.com/ses/;
# - https://aws.amazon.com/api-gateway/
API_SEND_MAIL=your_api_send_mail
5 changes: 3 additions & 2 deletions .github/docs/WANTTODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ First, Follow the [🤔 How to Use](./README.md#-how-to-use) steps.
## Contact Form

- Related to Contact Form:
- Create your account inside `emailjs` and make your changes.
- You can see [this video](https://www.youtube.com/watch?v=9HW3MZ_tsdo), to help you on practice.
- Check my api [here](https://github.com/felipecastrosales/site-api) and make your changes.
- You need configurate your AWS SES, and put your credentials inside the `.env` file.
- After that, configure AWS Lambda and API Gateway, and deploy your API.

## Firebase

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ firebase.json
firebase-config.js
.firebase
package.json

# Environment configuration
.env
lib/infra/env/env.g.dart
26 changes: 26 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "site",
"request": "launch",
"type": "dart",
"flutterMode": "debug"
},
{
"name": "site (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "site (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022-2023 Felipe Sales
Copyright (c) 2022-2024 Felipe Sales

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

With a single codebase, you can access this example from mobile, web and even desktop.

I'm sure this will be one of the best examples of the Flutter Web project in a completely open-source way and with the amout of features that exist.
I'm sure this will be one of the best examples of the Flutter Web project in a completely open-source way and with the amount of features that exist.

---

Expand Down Expand Up @@ -64,7 +64,7 @@ I'm sure this will be one of the best examples of the Flutter Web project in a c
- All of them using [`mocktail`](https://pub.dev/packages/mocktail).
- Internationalization:
- With support to 3 languages: English, Portuguese and Spanish;
- Feature to send an email to the user using [`emailjs API`](https://www.emailjs.com/);
- Feature to send an email to the user using [`AWS SES`](https://aws.amazon.com/ses/), [`AWS Lambda`](https://aws.amazon.com/lambda/) and [`AWS API Gateway`](https://aws.amazon.com/api-gateway/);
- Settings:
- Firebase Hosting;
- Google Domains;
Expand All @@ -88,7 +88,7 @@ Challenges are always an opportunity for growth, and in this project that became

One thing I realized was that Flutter Web still has a lot to evolve, but id does very well it proposes ([see here](https://docs.flutter.dev/development/platform-integration/web/faq#what-scenarios-are-ideal-for-flutter-on-the-web)). One of the main ones that still annoys me a little is the loading and rendering speed of the elements (there are some pre-load strategies, but that could be better and clearer IMHO.

I feel that the project can evolve a lot, and for that reason I was very carefull with its development. For it to be simple, scalable and capable of any developer, of any level, being able to use and understand it. Also, I'll always be on the lookout for issues and PRs to improve it. 🚀
I feel that the project can evolve a lot, and for that reason I was very carefully with its development. For it to be simple, scalable and capable of any developer, of any level, being able to use and understand it. Also, I'll always be on the lookout for issues and PRs to improve it. 🚀

This project took me out of my comfort zone, and I'm very happy with the result. Also, releasing it to the community did me a lot of good. Let's grow together, because the **Forge is Daily**. 🏆

Expand Down
60 changes: 30 additions & 30 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
include: package:flutter_lints/flutter.yaml

analyzer:
plugins:
- dart_code_metrics
# plugins:
# - dart_code_metrics
exclude:
- lib/generated_plugin_registrant.dart
- test/**
# - lib/generated_plugin_registrant.dart
# - test/**
- lib/app/core/l10n/localizations/** # Generated file
- lib/data/services/firebase/firebase_set_defaults.dart # To use dynamic type (because really need it)
# - lib/data/services/firebase/firebase_set_defaults.dart # To use dynamic type (because really need it)

linter:
rules:
Expand All @@ -28,28 +28,28 @@ linter:
- prefer_final_fields
- prefer_single_quotes

dart_code_metrics:
metrics:
cyclomatic-complexity: 20
number-of-parameters: 4
maximum-nesting-level: 5
metrics-exclude:
- test/**
rules:
- avoid-dynamic
- avoid-redundant-async
- avoid-passing-async-when-sync-expected
- avoid-redundant-async
- avoid-unnecessary-type-assertions
- avoid-unnecessary-type-casts
- avoid-unrelated-type-assertions
- avoid-unused-parameters
- avoid-nested-conditional-expressions
- newline-before-return
- no-boolean-literal-compare
- no-empty-block
- prefer-trailing-comma
- prefer-conditional-expressions
- no-equal-then-else
- prefer-moving-to-variable
- prefer-match-file-name
# dart_code_metrics:
# metrics:
# cyclomatic-complexity: 20
# number-of-parameters: 4
# maximum-nesting-level: 5
# metrics-exclude:
# - test/**
# rules:
# - avoid-dynamic
# - avoid-redundant-async
# - avoid-passing-async-when-sync-expected
# - avoid-redundant-async
# - avoid-unnecessary-type-assertions
# - avoid-unnecessary-type-casts
# - avoid-unrelated-type-assertions
# - avoid-unused-parameters
# - avoid-nested-conditional-expressions
# - newline-before-return
# - no-boolean-literal-compare
# - no-empty-block
# - prefer-trailing-comma
# - prefer-conditional-expressions
# - no-equal-then-else
# - prefer-moving-to-variable
# - prefer-match-file-name
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.felipecastrosales.site"
minSdkVersion 19
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.6.21'
ext.kotlin_version = '1.9.24'
repositories {
google()
mavenCentral()
Expand Down Expand Up @@ -29,6 +29,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
15 changes: 8 additions & 7 deletions lib/app/app_widget.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
import 'package:flutter/material.dart';

import 'package:firebase_remote_config/firebase_remote_config.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

import 'package:site/app/core/globals/globals.dart';
import 'package:site/app/core/injections/injections.dart';
import 'package:site/app/core/l10n/l10n.dart';
import 'package:site/app/core/themes/app_theme.dart';
import 'package:site/app/features/contact/contact.dart';
import 'package:site/app/features/home/home_page.dart';

class AppWidget extends StatelessWidget {
AppWidget({
super.key,
FirebaseRemoteConfig? firebaseRemoteConfig,
http.Client? httpClient,
ContactCubit? contactCubit,
}) : _firebaseRemoteConfig = firebaseRemoteConfig ?? getIt(),
_httpClient = httpClient ?? getIt();
_contactCubit = contactCubit ?? getIt();

final FirebaseRemoteConfig _firebaseRemoteConfig;
final http.Client _httpClient;
final ContactCubit _contactCubit;

@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: NavigationService.navigatorKey,
onGenerateTitle: (context) => AppTexts.get(context).projectTitle,
debugShowCheckedModeBanner: false,
theme: AppTheme.theme,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: HomePage(
firebaseRemoteConfig: _firebaseRemoteConfig,
httpClient: _httpClient,
contactCubit: _contactCubit,
),
);
}
Expand Down
1 change: 1 addition & 0 deletions lib/app/core/globals/globals.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'navigation_service.dart';
6 changes: 6 additions & 0 deletions lib/app/core/globals/navigation_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:flutter/material.dart';

class NavigationService {
static final navigatorKey = GlobalKey<NavigatorState>();
static final navigatorKeyContext = navigatorKey.currentContext;
}
29 changes: 14 additions & 15 deletions lib/app/core/injections/injections.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
import 'package:dio/dio.dart';
import 'package:firebase_remote_config/firebase_remote_config.dart';
import 'package:site/app/features/contact/contact.dart';
import 'package:get_it/get_it.dart';
import 'package:http/http.dart' as http;

import 'package:site/data/repositories/contact/contact.dart';
import 'package:site/data/services/firebase/firebase.dart';

final getIt = GetIt.I;

void configureDependencies() {
if (!getIt.isRegistered<http.Client>()) {
getIt.registerSingleton<http.Client>(
http.Client(),
if (!getIt.isRegistered<Dio>()) {
getIt.registerSingleton<Dio>(
Dio(),
);
}
if (!getIt.isRegistered<FirebaseRemoteConfig>()) {
getIt.registerSingleton<FirebaseRemoteConfig>(
FirebaseRemoteConfig.instance,
);
}
if (!getIt.isRegistered<FirebaseService>()) {
getIt.registerSingleton<FirebaseService>(
FirebaseServiceImpl(),
);
}
if (!getIt.isRegistered<ContactRepository>()) {
getIt.registerSingleton<ContactRepository>(
ContactRepositoryImpl(
firebaseRemoteConfig: getIt(),
getIt.registerLazySingleton<ContactRepository>(
() => ContactRepositoryImpl(
httpClient: getIt(),
),
);
}
if (!getIt.isRegistered<ContactCubit>()) {
getIt.registerFactory<ContactCubit>(
() => ContactCubit(
contactRepository: getIt(),
),
);
}
}
24 changes: 24 additions & 0 deletions lib/app/core/l10n/localizations/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,30 @@ abstract class AppLocalizations {
/// **'E-mail enviado com sucesso!'**
String get emailSendedWithSuccess;

/// No description provided for @emailNotSended.
///
/// In pt, this message translates to:
/// **'Erro ao enviar e-mail!'**
String get emailNotSended;

/// No description provided for @emailTooManyRequests.
///
/// In pt, this message translates to:
/// **'Tente novamente mais tarde!'**
String get emailTooManyRequests;

/// No description provided for @emailUnauthorized.
///
/// In pt, this message translates to:
/// **'O envio não foi autorizado!'**
String get emailUnauthorized;

/// No description provided for @emailUnknowError.
///
/// In pt, this message translates to:
/// **'Tente enviar de outra forma!'**
String get emailUnknowError;

/// No description provided for @letsChatCallMe.
///
/// In pt, this message translates to:
Expand Down
12 changes: 12 additions & 0 deletions lib/app/core/l10n/localizations/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get emailSendedWithSuccess => 'Email sent successfully!';

@override
String get emailNotSended => 'Error to send email';

@override
String get emailTooManyRequests => 'Please try again later!';

@override
String get emailUnauthorized => 'Sending was not authorized!';

@override
String get emailUnknowError => 'Try sending in another way!';

@override
String get letsChatCallMe => 'Let\'s chat, call me:';

Expand Down
12 changes: 12 additions & 0 deletions lib/app/core/l10n/localizations/app_localizations_es.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get emailSendedWithSuccess => '¡Email enviado exitosamente!';

@override
String get emailNotSended => '¡Error al enviar el email!';

@override
String get emailTooManyRequests => '¡Inténtalo de nuevo más tarde!';

@override
String get emailUnauthorized => '¡El envío no fue autorizado!';

@override
String get emailUnknowError => '¡Intenta enviar de otra manera!';

@override
String get letsChatCallMe => 'Hablemos, llámame:';

Expand Down
12 changes: 12 additions & 0 deletions lib/app/core/l10n/localizations/app_localizations_pt.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String get emailSendedWithSuccess => 'E-mail enviado com sucesso!';

@override
String get emailNotSended => 'Erro ao enviar e-mail!';

@override
String get emailTooManyRequests => 'Tente novamente mais tarde!';

@override
String get emailUnauthorized => 'O envio não foi autorizado!';

@override
String get emailUnknowError => 'Tente enviar de outra forma!';

@override
String get letsChatCallMe => 'Vamos bater um papo, me chame:';

Expand Down
Loading

0 comments on commit 265053b

Please sign in to comment.