diff --git a/AppShell.xaml b/AppShell.xaml
index 4f87549..37027f6 100644
--- a/AppShell.xaml
+++ b/AppShell.xaml
@@ -9,8 +9,10 @@
-
+
+
+
diff --git a/AppShell.xaml.cs b/AppShell.xaml.cs
index 5d609f4..52b9325 100644
--- a/AppShell.xaml.cs
+++ b/AppShell.xaml.cs
@@ -11,7 +11,7 @@ namespace Justice
Routing.RegisterRoute("LoginPage", typeof(Views.LoginPage));
Routing.RegisterRoute("DashboardPage", typeof(Views.DashboardPage));
- Routing.RegisterRoute("ViewReportsPage", typeof(Views.ViewReportsPage));
+ Routing.RegisterRoute("ViewReportsPage", typeof(Views.EndUserReportsPage));
LogoutCommand = new Command(async () =>
{
@@ -29,7 +29,7 @@ namespace Justice
base.OnNavigating(args);
// Check if user is authenticated
- if (!AuthHelper.IsLoggedIn && args.Target.Location.OriginalString.Contains("ViewReportsPage") || !AuthHelper.IsLoggedIn && args.Target.Location.OriginalString.Contains("DashboardPage"))
+ if (!AuthHelper.IsLoggedIn && args.Target.Location.OriginalString.Contains("EndUserReportPage") || !AuthHelper.IsLoggedIn && args.Target.Location.OriginalString.Contains("DashboardPage") || !AuthHelper.IsLoggedIn && args.Target.Location.OriginalString.Contains("AuthorityReportsPage"))
{
args.Cancel(); // Prevent navigation
await Shell.Current.GoToAsync("//LoginPage");
diff --git a/Helpers/DatabaseHelper.cs b/Helpers/DatabaseHelper.cs
index fd883e1..3ae342f 100644
--- a/Helpers/DatabaseHelper.cs
+++ b/Helpers/DatabaseHelper.cs
@@ -36,6 +36,10 @@ namespace Justice.Helpers
{
return await _database.DeleteAsync(item);
}
+ public async Task UpdateAsync(T item) where T : new()
+ {
+ return await _database.UpdateAsync(item);
+ }
public async Task FindAsync(string query, params object[] args) where T : new()
{
return await _database.FindWithQueryAsync(query, args);
diff --git a/Helpers/EmailService.cs b/Helpers/EmailService.cs
index 496d631..77c93ea 100644
--- a/Helpers/EmailService.cs
+++ b/Helpers/EmailService.cs
@@ -22,7 +22,7 @@ namespace Justice.Services
{
_incidentTypeToEmail = new Dictionary
{
- { "Accident", "amreitsyanf@gmail.com" },
+ { "Accident", "ambulancemaiti@gmail.com" },
{ "Crime", "crime-authority@example.com" },
{ "Fire", "fire-department@example.com" },
{ "Other", "general-authority@example.com" }
diff --git a/Helpers/GeoHelper.cs b/Helpers/GeoHelper.cs
index 8c828c7..c5c51c5 100644
--- a/Helpers/GeoHelper.cs
+++ b/Helpers/GeoHelper.cs
@@ -1,30 +1,28 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace Justice.Helpers
{
- public class GeoHelper
+ public static class GeoHelper
{
- public static double CalculateDistance(double latitude1, double longitude1, double latitude2, double longitude2)
+ public static double CalculateDistance(double lat1, double lon1, double lat2, double lon2)
{
- double radianLat1 = Math.PI * latitude1 / 100;
- double radianLat2 = Math.PI * latitude2 / 100;
- double radianLong1 = Math.PI * longitude1 / 100;
- double radianLong2 = Math.PI * longitude2 / 100;
+ const double EarthRadiusKm = 6371;
- double dLong = radianLong2 - radianLong1;
- double dLat = radianLat2 - radianLat1;
- double a = Math.Pow(Math.Sin(dLat / 2), 2) +
- Math.Cos(radianLat1) * Math.Cos(radianLat2) *
- Math.Pow(Math.Sin(dLong / 2),2);
- double c = 2 * Math.Asin(Math.Sqrt(a));
- const double radius = 6371; //radius of earth in kilometer
- double distance = radius * c;
+ double dLat = DegreesToRadians(lat2 - lat1);
+ double dLon = DegreesToRadians(lon2 - lon1);
- return distance;
+ double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
+ Math.Cos(DegreesToRadians(lat1)) * Math.Cos(DegreesToRadians(lat2)) *
+ Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
+
+ double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
+
+ return EarthRadiusKm * c;
+ }
+
+ private static double DegreesToRadians(double degrees)
+ {
+ return degrees * Math.PI / 180;
}
}
}
diff --git a/Justice.csproj b/Justice.csproj
index fbc1f82..e5bdb4f 100644
--- a/Justice.csproj
+++ b/Justice.csproj
@@ -85,12 +85,18 @@
MSBuild:Compile
+
+ MSBuild:Compile
+
MSBuild:Compile
MSBuild:Compile
+
+ MSBuild:Compile
+
MSBuild:Compile
@@ -109,9 +115,6 @@
MSBuild:Compile
-
- MSBuild:Compile
-
diff --git a/Justice.csproj.user b/Justice.csproj.user
index bc2dc16..fadeb8c 100644
--- a/Justice.csproj.user
+++ b/Justice.csproj.user
@@ -17,12 +17,18 @@
Designer
+
+ Designer
+
Designer
Designer
+
+ Designer
+
Designer
@@ -41,9 +47,6 @@
Designer
-
- Designer
-
diff --git a/Models/Authority.cs b/Models/Authority.cs
index a8a4d33..124e5ce 100644
--- a/Models/Authority.cs
+++ b/Models/Authority.cs
@@ -13,5 +13,6 @@ namespace Justice.Models
public double Latitude { get; set; }
public double Longitude { get; set; }
public string AuthorityType { get; set; }
+ public string ResponsibleFor { get; set; }
}
}
diff --git a/Models/IncidentReport.cs b/Models/IncidentReport.cs
index 57116b2..a2d4a74 100644
--- a/Models/IncidentReport.cs
+++ b/Models/IncidentReport.cs
@@ -1,4 +1,5 @@
-using SQLite;
+using Org.BouncyCastle.Bcpg;
+using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -19,5 +20,7 @@ namespace Justice.Models
public string Address { get; set; }
public DateTime DateTime { get; set; }
public string AttachmentPath { get; set; }
+ public string Status { get; set; }
+ public string AssignedAuthority { get; set; }
}
}
diff --git a/Resources/Images/logo.png b/Resources/Images/logo.png
new file mode 100644
index 0000000..e1ba3c0
Binary files /dev/null and b/Resources/Images/logo.png differ
diff --git a/Services/AuthorityService.cs b/Services/AuthorityService.cs
index e9922c4..205ffa4 100644
--- a/Services/AuthorityService.cs
+++ b/Services/AuthorityService.cs
@@ -16,8 +16,10 @@ namespace Justice.Services
new Authority { Name = "Police", Email = "amritsyangtan1@gmail.com", Latitude = 47.7008, Longitude = 60.3000, AuthorityType = "Accident" },
new Authority { Name = "Police", Email = "amreitsyanf@gmail.com", Latitude = 27.7008, Longitude = 85.3000, AuthorityType = "Accident" },
new Authority { Name = "Fire Department", Email = "amAritsyangtan1@gmail.com", Latitude = 27.7110, Longitude = 85.2915, AuthorityType = "Fire" },
+ new Authority { Name = "Crime", Email = "amritsyangtan1@gmail.com", Latitude = 47.7110, Longitude = 90.2915, AuthorityType = "Police" },
+ new Authority { Name = "Crime", Email = "amreitsyanf@gmail.com", Latitude = 30.7110, Longitude = 80.2915, AuthorityType = "Police" },
new Authority { Name = "Ambulance", Email = "ambulance@example.com", Latitude = 27.7052, Longitude = 85.3092, AuthorityType = "Ambulance" }
- };
+ };
public List GetNearByAuthorities(double incidentLatitude, double incidentLongitude, double radiusKm = 10)
{
List nearbyAuthorities = new List();
diff --git a/Views/AuthorityReportsPage.xaml b/Views/AuthorityReportsPage.xaml
new file mode 100644
index 0000000..9a4ae7c
--- /dev/null
+++ b/Views/AuthorityReportsPage.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Views/AuthorityReportsPage.xaml.cs b/Views/AuthorityReportsPage.xaml.cs
new file mode 100644
index 0000000..00aac0c
--- /dev/null
+++ b/Views/AuthorityReportsPage.xaml.cs
@@ -0,0 +1,93 @@
+using Justice.Helpers;
+using Justice.Models;
+using System.Collections.ObjectModel;
+using Justice.Services;
+
+namespace Justice.Views
+{
+ public partial class AuthorityReportsPage : ContentPage
+ {
+ private readonly DatabaseHelper _dbHelper;
+ public ObservableCollection Reports { get; set; }
+
+ public AuthorityReportsPage()
+ {
+ InitializeComponent();
+ _dbHelper = new DatabaseHelper();
+ Reports = new ObservableCollection();
+ ReportsListView.ItemsSource = Reports;
+ }
+
+ protected override async void OnAppearing()
+ {
+ base.OnAppearing();
+ await LoadReportsAsync();
+ }
+
+ private async Task LoadReportsAsync()
+ {
+ try
+ {
+ Reports.Clear();
+ var reportsFromDb = await _dbHelper.GetAllAsync();
+ foreach (var report in reportsFromDb)
+ {
+ Reports.Add(report);
+ }
+ }
+ catch (Exception ex)
+ {
+ await DisplayAlert("Error", $"Failed to load reports: {ex.Message}", "OK");
+ }
+ }
+
+ private async void OnUpdateStatusClicked(object sender, EventArgs e)
+ {
+ var button = sender as Button;
+ if (button?.CommandParameter is IncidentReport selectedReport)
+ {
+ selectedReport.Status = "Resolved";
+
+ try
+ {
+ await _dbHelper.UpdateAsync(selectedReport);
+ await DisplayAlert("Success", "Status updated to Resolved.", "OK");
+
+ // Push notification to end user (dummy logic)
+ await DisplayAlert("Notification", $"Notification sent to {selectedReport.ReporterName}.", "OK");
+ await LoadReportsAsync();
+ }
+ catch (Exception ex)
+ {
+ await DisplayAlert("Error", $"Failed to update status: {ex.Message}", "OK");
+ }
+ }
+ }
+
+ private async void OnViewAttachmentClicked(object sender, EventArgs e)
+ {
+ var button = sender as Button;
+ if (button?.CommandParameter is IncidentReport selectedReport)
+ {
+ if (!string.IsNullOrEmpty(selectedReport.AttachmentPath))
+ {
+ try
+ {
+ await Launcher.OpenAsync(new OpenFileRequest
+ {
+ File = new ReadOnlyFile(selectedReport.AttachmentPath)
+ });
+ }
+ catch (Exception ex)
+ {
+ await DisplayAlert("Error", $"Failed to open attachment: {ex.Message}", "OK");
+ }
+ }
+ else
+ {
+ await DisplayAlert("Error", "No attachment found for this report.", "OK");
+ }
+ }
+ }
+ }
+}
diff --git a/Views/DashboardPage.xaml b/Views/DashboardPage.xaml
index 177a4f6..b36649b 100644
--- a/Views/DashboardPage.xaml
+++ b/Views/DashboardPage.xaml
@@ -141,13 +141,6 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Views/DashboardPage.xaml.cs b/Views/DashboardPage.xaml.cs
index 13e7421..f361c93 100644
--- a/Views/DashboardPage.xaml.cs
+++ b/Views/DashboardPage.xaml.cs
@@ -24,7 +24,7 @@ public partial class DashboardPage : ContentPage
private void OnViewReportClicked(object sender, EventArgs e)
{
- Navigation.PushAsync(new ViewReportsPage());
+ Navigation.PushAsync(new EndUserReportsPage());
}
private void OnIncidentReportClicked(object sender, EventArgs e)
{
diff --git a/Views/EndUserReportsPage.xaml b/Views/EndUserReportsPage.xaml
new file mode 100644
index 0000000..646f08d
--- /dev/null
+++ b/Views/EndUserReportsPage.xaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Views/EndUserReportsPage.xaml.cs b/Views/EndUserReportsPage.xaml.cs
new file mode 100644
index 0000000..b83fefe
--- /dev/null
+++ b/Views/EndUserReportsPage.xaml.cs
@@ -0,0 +1,43 @@
+using Justice.Helpers;
+using Justice.Models;
+using System.Collections.ObjectModel;
+
+namespace Justice.Views
+{
+ public partial class EndUserReportsPage : ContentPage
+ {
+ private readonly DatabaseHelper _dbHelper;
+ public ObservableCollection Reports { get; set; }
+
+ public EndUserReportsPage()
+ {
+ InitializeComponent();
+ _dbHelper = new DatabaseHelper();
+ Reports = new ObservableCollection();
+ ReportsListView.ItemsSource = Reports;
+ }
+
+ protected override async void OnAppearing()
+ {
+ base.OnAppearing();
+ await LoadReportsAsync();
+ }
+
+ private async Task LoadReportsAsync()
+ {
+ try
+ {
+ Reports.Clear();
+ var reportsFromDb = await _dbHelper.GetAllAsync();
+ foreach (var report in reportsFromDb)
+ {
+ Reports.Add(report);
+ }
+ }
+ catch (Exception ex)
+ {
+ await DisplayAlert("Error", $"Failed to load reports: {ex.Message}", "OK");
+ }
+ }
+ }
+}
diff --git a/Views/IncidentReportPage.xaml.cs b/Views/IncidentReportPage.xaml.cs
index 1b4123e..d64f361 100644
--- a/Views/IncidentReportPage.xaml.cs
+++ b/Views/IncidentReportPage.xaml.cs
@@ -135,7 +135,6 @@ namespace Justice.Views
foreach (var authority in nearbyAuthorities)
{
bool emailSent = await _emailService.SendEmailWithAttachmentAsync(authority.Email, "Incident Report", emailBody, _selectedAttachmentPath);
-
if (emailSent)
{
Console.WriteLine($"Email sent to: {authority.Name}");
diff --git a/Views/LoginPage.xaml.cs b/Views/LoginPage.xaml.cs
index 6456285..fd1a9e2 100644
--- a/Views/LoginPage.xaml.cs
+++ b/Views/LoginPage.xaml.cs
@@ -49,7 +49,7 @@ namespace Justice.Views
else if (enteredUsername == authvalidUsername && enteredPassword == authvalidPassword && selectedRole == "Authority User")
{
AuthHelper.Login("AuthorityUser");
- await Shell.Current.GoToAsync("//ViewReportsPage");
+ await Shell.Current.GoToAsync("//AuthorityReportsPage");
}
else
{
diff --git a/Views/ViewReportsPage.xaml b/Views/ViewReportsPage.xaml
deleted file mode 100644
index 41eb8bd..0000000
--- a/Views/ViewReportsPage.xaml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Views/ViewReportsPage.xaml.cs b/Views/ViewReportsPage.xaml.cs
deleted file mode 100644
index fc67c73..0000000
--- a/Views/ViewReportsPage.xaml.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using Justice.Helpers;
-using Justice.Models;
-using System;
-using System.Collections.ObjectModel;
-using System.Threading.Tasks;
-using Justice.Services;
-
-namespace Justice.Views
-{
- public partial class ViewReportsPage : ContentPage
- {
- private readonly DatabaseHelper _databaseHelper;
- public ObservableCollection Reports { get; set; }
-
- public ViewReportsPage()
- {
- InitializeComponent();
- _databaseHelper = new DatabaseHelper();
- Reports = new ObservableCollection();
- ReportsListView.ItemsSource = Reports;
- }
-
- protected override async void OnAppearing()
- {
- base.OnAppearing();
- await LoadReportsAsync();
- }
-
- private async Task LoadReportsAsync()
- {
- try
- {
- var reportsFromDb = await _databaseHelper.GetAllAsync();
- Reports.Clear();
-
- foreach (var report in reportsFromDb)
- {
- Reports.Add(report);
- }
- }
- catch (Exception ex)
- {
- await DisplayAlert("Error", $"Failed to load reports: {ex.Message}", "OK");
- }
- }
-
- private async void OnReportSelected(object sender, SelectedItemChangedEventArgs e)
- {
- if (e.SelectedItem is IncidentReport selectedReport)
- {
- await DisplayAlert("Report Details",
- $"Type: {selectedReport.IncidentType}\n" +
- $"Description: {selectedReport.Description}\n" +
- $"Address: {selectedReport.Address}\n" +
- $"Submitted on: {selectedReport.DateTime:MMM dd, yyyy HH:mm}\n" +
- $"Attachment: {(string.IsNullOrWhiteSpace(selectedReport.AttachmentPath) ? "None" : "Attached")}",
- "OK");
-
- // Deselect the item
- ReportsListView.SelectedItem = null;
- }
- }
- private async void OnDeleteReportClicked(object sender, EventArgs e)
- {
- // Get the button's binding context
- if (sender is Button deleteButton && deleteButton.CommandParameter is IncidentReport reportToDelete)
- {
- bool confirm = await DisplayAlert("Delete Report", "Are you sure you want to delete this report?", "Yes", "No");
- if (confirm)
- {
- try
- {
- // Delete the report from the database
- await _databaseHelper.DeleteAsync(reportToDelete);
-
- // Remove the report from the ObservableCollection
- Reports.Remove(reportToDelete);
-
- await DisplayAlert("Success", "Report deleted successfully.", "OK");
- }
- catch (Exception ex)
- {
- await DisplayAlert("Error", $"Failed to delete report: {ex.Message}", "OK");
- }
- }
- }
- }
- private async void OnLogoutClicked(object sender, EventArgs e)
- {
- bool confirm = await DisplayAlert("Logout", "Are you sure you want to log out?", "Yes", "No");
- if (confirm)
- {
- // Redirect to Login Page
- await Shell.Current.GoToAsync("//LoginPage");
- }
- }
- private void MenuItem_Clicked(object sender, EventArgs e)
- {
-
- }
- }
-}