Loader Update

main
unknown 6 months ago
parent 28afc9a2a5
commit 554dd75474
  1. 3
      App.xaml.cs
  2. 44
      Helpers/EmailService.cs
  3. 1
      Justice.csproj
  4. 4
      Justice.csproj.user
  5. 18
      Views/IncidentReportPage.xaml
  6. 78
      Views/IncidentReportPage.xaml.cs
  7. BIN
      bin/Debug/net9.0-android/Justice.dll
  8. BIN
      bin/Debug/net9.0-android/Justice.pdb
  9. 22
      bin/Debug/net9.0-android/Justice.xml
  10. BIN
      bin/Debug/net9.0-ios/iossimulator-x64/Justice.dll
  11. BIN
      bin/Debug/net9.0-ios/iossimulator-x64/Justice.pdb
  12. BIN
      bin/Debug/net9.0-maccatalyst/maccatalyst-x64/Justice.dll
  13. BIN
      bin/Debug/net9.0-maccatalyst/maccatalyst-x64/Justice.pdb
  14. BIN
      bin/Debug/net9.0-windows10.0.19041.0/win10-x64/Justice.dll
  15. BIN
      bin/Debug/net9.0-windows10.0.19041.0/win10-x64/Justice.exe
  16. BIN
      bin/Debug/net9.0-windows10.0.19041.0/win10-x64/Justice.pdb

@ -16,7 +16,8 @@ namespace Justice
try
{
var dbHelper = new DatabaseHelper();
await dbHelper.InitializeAsync<EmergencyContact>(); // Asynchronously create the EmergencyContact table
await dbHelper.InitializeAsync<EmergencyContact>();
await dbHelper.InitializeAsync<IncidentReport>();// Asynchronously create the EmergencyContact table
}
catch (Exception ex)
{

@ -1,22 +1,25 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
namespace ChildGuard.Services
namespace Justice.Services
{
public class EmailService
{
private readonly string _smtpServer = "smtp.gmail.com";
private readonly int _smtpPort = 587;
private readonly string _senderEmail = "amritsyangtan1@gmail.com"; // Replace with your email
private readonly string _senderPassword = "bdcx ycpy cbrr szpm"; // Replace with your app password
private readonly string _senderEmail = "amritsyangtan1@gmail.com";
private readonly string _senderPassword = "bdcx ycpy cbrr szpm";
// Map incident types to recipient emails
private readonly Dictionary<string, string> _incidentTypeToEmail;
public EmailService()
{
// Map incident types to authority emails
_incidentTypeToEmail = new Dictionary<string, string>
{
{ "Accident", "amreitsyanf@gmail.com" },
@ -27,13 +30,19 @@ namespace ChildGuard.Services
}
/// <summary>
/// Sends an email using SMTP.
/// Gets the recipient email address based on the incident type.
/// </summary>
/// <param name="incidentType">The type of the incident.</param>
/// <returns>The email address of the recipient.</returns>
public string GetRecipientEmail(string incidentType)
{
return _incidentTypeToEmail.TryGetValue(incidentType, out var email) ? email : "amreitsyanf@gmail.com";
}
/// <summary>
/// Sends an email with an optional attachment.
/// </summary>
/// <param name="recipientEmail">Recipient's email address.</param>
/// <param name="subject">Email subject.</param>
/// <param name="body">Email body.</param>
/// <returns>True if successful, otherwise false.</returns>
public async Task<bool> SendEmailAsync(string recipientEmail, string subject, string body)
public async Task<bool> SendEmailWithAttachmentAsync(string recipientEmail, string subject, string body, string attachmentPath)
{
try
{
@ -52,6 +61,11 @@ namespace ChildGuard.Services
mailMessage.To.Add(recipientEmail);
if (!string.IsNullOrWhiteSpace(attachmentPath) && File.Exists(attachmentPath))
{
mailMessage.Attachments.Add(new Attachment(attachmentPath));
}
await smtpClient.SendMailAsync(mailMessage);
}
@ -64,15 +78,5 @@ namespace ChildGuard.Services
return false;
}
}
/// <summary>
/// Gets the recipient email based on the incident type.
/// </summary>
/// <param name="incidentType">Incident type.</param>
/// <returns>Recipient email address.</returns>
public string GetRecipientEmail(string incidentType)
{
return _incidentTypeToEmail.TryGetValue(incidentType, out var email) ? email : "default-authority@example.com";
}
}
}

@ -60,6 +60,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="MailKit" Version="4.9.0" />
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.22" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" />
<PackageReference Include="Microsoft.Maui.Maps" Version="9.0.22" />

@ -3,8 +3,8 @@
<PropertyGroup>
<IsFirstTimeProjectOpen>False</IsFirstTimeProjectOpen>
<ActiveDebugFramework>net9.0-android</ActiveDebugFramework>
<ActiveDebugProfile>Medium Phone API 35 (Android 15.0 - API 35)</ActiveDebugProfile>
<SelectedPlatformGroup>Emulator</SelectedPlatformGroup>
<ActiveDebugProfile>Samsung SM-M325F (Android 13.0 - API 33)</ActiveDebugProfile>
<SelectedPlatformGroup>PhysicalDevice</SelectedPlatformGroup>
<DefaultDevice>Medium_Phone_API_35</DefaultDevice>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net9.0-android|AnyCPU'">

@ -5,11 +5,9 @@
<ScrollView>
<StackLayout Padding="20" Spacing="15">
<!-- Reporter Name -->
<Label Text="Your Name" FontSize="Medium" />
<Entry x:Name="ReporterNameEntry" Placeholder="Enter your name" />
<!-- Incident Type -->
<Label Text="Incident Type" FontSize="Medium" />
<Picker x:Name="IncidentTypePicker">
<Picker.ItemsSource>
@ -22,20 +20,24 @@
</Picker.ItemsSource>
</Picker>
<!-- Description -->
<Label Text="Description" FontSize="Medium" />
<Editor x:Name="DescriptionEditor" Placeholder="Enter incident details" AutoSize="TextChanges" />
<!-- Location -->
<Label Text="Location (Auto-filled)" FontSize="Medium" />
<Entry x:Name="LocationEntry" IsReadOnly="True" />
<Label Text="Address" FontSize="Medium" />
<Entry x:Name="LocationEntry" IsReadOnly="False" />
<!-- Attachment -->
<Label Text="Attachment (Optional)" FontSize="Medium" />
<Button Text="Choose File" Clicked="OnChooseFileClicked" />
<Label x:Name="AttachmentLabel" Text="No file selected" FontSize="Small" TextColor="Gray" />
<!-- Submit Button -->
<Button Text="Submit Report" Clicked="OnSubmitReportClicked" />
<ActivityIndicator x:Name="LoadingIndicator"
IsRunning="True"
IsVisible="True"
VerticalOptions="Center"
HorizontalOptions="Center"
Color="Blue"/>
</StackLayout>
</ScrollView>
</ContentPage>

@ -1,7 +1,11 @@
using ChildGuard.Services;
using Justice.Services;
using Justice.Helpers;
using Justice.Models;
using Microsoft.Maui.Storage;
using System;
using System.IO;
using System.Threading.Tasks;
using MailKit;
namespace Justice.Views
{
@ -9,6 +13,7 @@ namespace Justice.Views
{
private readonly DatabaseHelper _databaseHelper;
private readonly EmailService _emailService;
private string _selectedAttachmentPath; // Store the file path of the selected attachment
public IncidentReportPage()
{
@ -17,6 +22,12 @@ namespace Justice.Views
_emailService = new EmailService();
}
public async Task SetLoadingStateAsync(bool isLoading)
{
LoadingIndicator.IsRunning = isLoading;
LoadingIndicator.IsVisible = isLoading;
}
protected override async void OnAppearing()
{
base.OnAppearing();
@ -29,14 +40,58 @@ namespace Justice.Views
{
var (latitude, longitude, address) = await GeolocationHelper.GetLocationAsync();
LocationEntry.Text = address;
}
catch (Exception ex)
{
LocationEntry.Text = "Unable to fetch location.";
Console.WriteLine($"Error fetching location: {ex.Message}");
}
finally
{
await SetLoadingStateAsync(false);
}
}
private async void OnChooseFileClicked(object sender, EventArgs e)
{
try
{
var customFileType = new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
{
{ DevicePlatform.Android, new[] { "*/*" } }, // Allow all files on Android
{ DevicePlatform.iOS, new[] { "public.data" } }, // iOS equivalent for all files
{ DevicePlatform.WinUI, new[] { "*" } } // Allow all files on Windows
});
var pickOptions = new PickOptions
{
PickerTitle = "Select a file",
FileTypes = customFileType
};
var result = await FilePicker.PickAsync(pickOptions);
if (result != null)
{
// Save the file path
_selectedAttachmentPath = result.FullPath;
AttachmentLabel.Text = $"Selected File: {Path.GetFileName(_selectedAttachmentPath)}";
}
else
{
AttachmentLabel.Text = "No file selected";
}
}
catch (Exception ex)
{
Console.WriteLine($"File selection error: {ex.Message}");
await DisplayAlert("Error", "Failed to select file.", "OK");
}
}
private async void OnSubmitReportClicked(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(ReporterNameEntry.Text) ||
@ -58,18 +113,19 @@ namespace Justice.Views
Longitude = longitude,
Address = address,
DateTime = DateTime.Now,
AttachmentPath = null // Optional
AttachmentPath = _selectedAttachmentPath // Save the attachment path
};
try
{
// Save to database
// Save the report to the database
await SetLoadingStateAsync(true);
await _databaseHelper.InsertAsync(report);
// Get recipient email based on incident type
// Get the recipient email based on the incident type
string recipientEmail = _emailService.GetRecipientEmail(report.IncidentType);
// Prepare email content
// Prepare the email content
string emailBody = $"Incident Report:\n\n" +
$"Name: {report.ReporterName}\n" +
$"Type: {report.IncidentType}\n" +
@ -80,7 +136,7 @@ namespace Justice.Views
$"Date/Time: {report.DateTime}";
// Send email
bool emailSent = await _emailService.SendEmailAsync(recipientEmail, "Incident Report", emailBody);
bool emailSent = await _emailService.SendEmailWithAttachmentAsync(recipientEmail, "Incident Report", emailBody, _selectedAttachmentPath);
if (emailSent)
{
@ -95,15 +151,11 @@ namespace Justice.Views
{
await DisplayAlert("Error", $"Failed to submit report: {ex.Message}", "OK");
}
}
private async void OnChooseFileClicked(object sender, EventArgs e)
{
var result = await FilePicker.PickAsync();
if (result != null)
finally
{
await DisplayAlert("File Selected", $"File: {result.FileName}", "OK");
await SetLoadingStateAsync(false);
}
}
}
}

@ -10,27 +10,23 @@
</summary>
<returns>A tuple containing Latitude, Longitude, and Address.</returns>
</member>
<member name="T:Justice.Resource">
<member name="M:Justice.Services.EmailService.GetRecipientEmail(System.String)">
<summary>
Android Resource Designer class.
Exposes the Android Resource designer assembly into the project Namespace.
Gets the recipient email address based on the incident type.
</summary>
<param name="incidentType">The type of the incident.</param>
<returns>The email address of the recipient.</returns>
</member>
<member name="M:ChildGuard.Services.EmailService.SendEmailAsync(System.String,System.String,System.String)">
<member name="M:Justice.Services.EmailService.SendEmailWithAttachmentAsync(System.String,System.String,System.String,System.String)">
<summary>
Sends an email using SMTP.
Sends an email with an optional attachment.
</summary>
<param name="recipientEmail">Recipient's email address.</param>
<param name="subject">Email subject.</param>
<param name="body">Email body.</param>
<returns>True if successful, otherwise false.</returns>
</member>
<member name="M:ChildGuard.Services.EmailService.GetRecipientEmail(System.String)">
<member name="T:Justice.Resource">
<summary>
Gets the recipient email based on the incident type.
Android Resource Designer class.
Exposes the Android Resource designer assembly into the project Namespace.
</summary>
<param name="incidentType">Incident type.</param>
<returns>Recipient email address.</returns>
</member>
</members>
</doc>

Loading…
Cancel
Save