Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
<WarningLevel>4</WarningLevel>
<AndroidManagedSymbols>true</AndroidManagedSymbols>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<CustomCommands>
<CustomCommands>
<Command>
<type>Build</type>
</Command>
</CustomCommands>
</CustomCommands>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
Expand Down
1 change: 1 addition & 0 deletions UndoAssessment/UndoAssessment/AppShell.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<TabBar>
<ShellContent Title="About" Icon="icon_about.png" Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
<ShellContent Title="Browse" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:ItemsPage}" />
<ShellContent Title="Test" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:ApiPage}" />
</TabBar>

<!--
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace UndoAssessment.Services
{
public class ApiRequestException : Exception
{
public ApiRequestException(string message) : base(message)
{
}
}
}
31 changes: 31 additions & 0 deletions UndoAssessment/UndoAssessment/Helpers/ApiRequestHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Threading.Tasks;
using UndoAssessment.Models;
using UndoAssessment.Services;
using Xamarin.Forms;

namespace UndoAssessment.Helpers
{
public static class ApiRequestHandler
{
public static async Task DisplaySuccessMessage(ApiResponseModel apiResponseModel)
{
await Application.Current.MainPage.DisplayAlert("Success", apiResponseModel.Message, "OK");
}

public static async Task DisplayErrorMessage(ApiResponseModel apiResponseModel)
{
await Application.Current.MainPage.DisplayAlert("API Error", apiResponseModel.Message, "OK");
}

public static async Task DisplayApiErrorMessage(string message)
{
await Application.Current.MainPage.DisplayAlert("API Error", message, "OK");
}

public static async Task HandleApiRequestException(ApiRequestException ex)
{
await Application.Current.MainPage.DisplayAlert("API Error", ex.Message, "OK");
}
}
}
19 changes: 19 additions & 0 deletions UndoAssessment/UndoAssessment/Helpers/ValidationHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Linq;

namespace UndoAssessment.Helpers
{
public static class ValidationHelper
{
public static bool IsNameValid(string name)
{
// For example, check for illegal characters or minimum length
return !string.IsNullOrWhiteSpace(name);
}

public static bool IsAgeValid(string age)
{
// For example, check if it's a numeric value or within a certain range
return int.TryParse(age, out _) && !string.IsNullOrWhiteSpace(age);
}
}
}
19 changes: 19 additions & 0 deletions UndoAssessment/UndoAssessment/Models/ApiResponseModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using Newtonsoft.Json;

namespace UndoAssessment.Models
{
public class ApiResponseModel
{
[JsonProperty("errorCode")]
public int ErrorCode { get; set; }

[JsonProperty("message")]
public string Message { get; set; }

[JsonProperty("date")]
public string Date { get; set; }
}

}

8 changes: 8 additions & 0 deletions UndoAssessment/UndoAssessment/Models/UserModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace UndoAssessment.Models
{
public class UserModel
{
public string Name { get; set; }
public string Age { get; set; }
}
}
21 changes: 21 additions & 0 deletions UndoAssessment/UndoAssessment/Services/ApiService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Threading.Tasks;
using UndoAssessment.Models;
using UndoAssessment.Services.Base;

namespace UndoAssessment.Services
{
public class ApiService : BaseApiService
{
public async Task<ApiResponseModel> InvokeSuccessEndpoint()
{
var response = await InvokeEndpoint("https://malkarakundostagingpublicapi.azurewebsites.net/success");
return ExtractApiResponse(response);
}

public async Task<ApiResponseModel> InvokeFailEndpoint()
{
var response = await InvokeEndpoint("https://malkarakundostagingpublicapi.azurewebsites.net/fail");
return ExtractApiResponse(response);
}
}
}
47 changes: 47 additions & 0 deletions UndoAssessment/UndoAssessment/Services/Base/BaseApiService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UndoAssessment.Models;

namespace UndoAssessment.Services.Base
{
public class BaseApiService
{
protected async Task<string> InvokeEndpoint(string url)
{
try
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);

var content = await response.Content.ReadAsStringAsync();
return content;
}
catch (HttpRequestException ex)
{
var content = ex.Message;
throw new ApiRequestException(content);
}
}

protected ApiResponseModel ExtractApiResponse(string response)
{
try
{
var apiResponse = JsonConvert.DeserializeObject<ApiResponseModel>(response);
return apiResponse;
}
catch (JsonException ex)
{
Console.WriteLine($"Failed to deserialize API response: {ex.Message}");
return null;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to extract API response: {ex.Message}");
return null;
}
}
}
}
14 changes: 14 additions & 0 deletions UndoAssessment/UndoAssessment/UndoAssessment.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,24 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
<BuildWithMSBuildOnMono>true</BuildWithMSBuildOnMono>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2578" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.6" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<None Remove="Helpers\" />
<None Remove="Services\Base\" />
<None Remove="Core\" />
<None Remove="Core\Exceptions\" />
</ItemGroup>
<ItemGroup>
<Folder Include="Helpers\" />
<Folder Include="Services\Base\" />
<Folder Include="Core\" />
<Folder Include="Core\Exceptions\" />
</ItemGroup>
</Project>
114 changes: 114 additions & 0 deletions UndoAssessment/UndoAssessment/ViewModels/ApiPageViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using UndoAssessment.Helpers;
using UndoAssessment.Models;
using UndoAssessment.Services;
using Xamarin.Forms;

namespace UndoAssessment.ViewModels
{
public class ApiPageViewModel : INotifyPropertyChanged
{
private UserModel _user;
public UserModel User
{
get { return _user; }
set
{
_user = value;
OnPropertyChanged(nameof(User));
}
}

private bool _isUserInformationVisible;
public bool IsUserInformationVisible
{
get { return _isUserInformationVisible; }
set
{
_isUserInformationVisible = value;
OnPropertyChanged(nameof(IsUserInformationVisible));
}
}

private readonly ApiService _apiService;

public ApiPageViewModel()
{
_apiService = new ApiService();
User = new UserModel();
IsUserInformationVisible = false;
}


public async Task InvokeSuccessEndpoint()
{
try
{
var response = await _apiService.InvokeSuccessEndpoint();
await ApiRequestHandler.DisplaySuccessMessage(response);
}
catch (ApiRequestException ex)
{
await ApiRequestHandler.HandleApiRequestException(ex);
}
}

public async Task InvokeFailEndpoint()
{
try
{
var response = await _apiService.InvokeFailEndpoint();
await ApiRequestHandler.DisplayErrorMessage(response);
}
catch (ApiRequestException ex)
{
await ApiRequestHandler.HandleApiRequestException(ex);
}
}




public async Task AddUserInformation()
{
var name = await Application.Current.MainPage.DisplayPromptAsync("User Information", "Enter your name");
var age = await Application.Current.MainPage.DisplayPromptAsync("User Information", "Enter your age");

if (!string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(age))
{
// Validate age
if (!ValidationHelper.IsAgeValid(age))
{
await Application.Current.MainPage.DisplayAlert("Error", "Invalid age. Please enter a numeric value for age.", "OK");
return;
}

// Validate name
if (!ValidationHelper.IsNameValid(name))
{
await Application.Current.MainPage.DisplayAlert("Error", "Invalid name. Please enter a valid name.", "OK");
return;
}

User.Name = name;
User.Age = age;
IsUserInformationVisible = true;

OnPropertyChanged(nameof(User));
}
}



public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
31 changes: 31 additions & 0 deletions UndoAssessment/UndoAssessment/Views/ApiPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:UndoAssessment.ViewModels;assembly=UndoAssessment"
x:Class="UndoAssessment.Views.ApiPage"
Padding="25">
<ContentPage.BindingContext>
<viewmodels:ApiPageViewModel />
</ContentPage.BindingContext>
<StackLayout Padding="20">
<StackLayout HorizontalOptions="End">
<Button Text="Add User Information"
Clicked="OnAddUserButtonClicked" />
</StackLayout>

<StackLayout VerticalOptions="CenterAndExpand">
<StackLayout x:Name="userDataLayout" IsVisible="{Binding IsUserInformationVisible}">
<Label Text="User Information" FontAttributes="Bold" />
<Label Text="{Binding User.Name, Mode=TwoWay}" />
<Label Text="{Binding User.Age, Mode=TwoWay}" />
</StackLayout>
</StackLayout>

<StackLayout HorizontalOptions="End">
<Button Text="Invoke Success Endpoint"
Clicked="OnSuccessButtonClicked" />
<Button Text="Invoke Fail Endpoint"
Clicked="OnFailButtonClicked" />
</StackLayout>

</StackLayout>
</ContentPage>
Loading