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
46 changes: 46 additions & 0 deletions PleaseReadMyAnswer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Assessment Finished By Manric Vilegas

## Task 1 [4 hours]

Dear Cate

I have finished second update about this project.
Please check it.

## Task 2 [2 hours]

- Design the User Interface (UI / UX):

Decide on the layout and appearance of the news section within the home tab.
Consider using a ListView or RecyclerView to display the news articles in a scrollable list.

- Fetching News Data:

Determine the source(s) from where I will retrieve the news data. This could be an API, RSS feed, or a content management system (CMS) if the client has one.
Implement the necessary logic to fetch news data from the chosen source(s).
Use libraries like Newtonsoft.Json or System.Net.Http for making HTTP requests and handling JSON data.
- Parse and Store News Data:

Receive the news data, parse it according to the provided format (JSON, XML, etc.).
Extract relevant information such as article title, description, publication date, and image URL.
Create a model class to represent the news articles and store this data in an appropriate data structure, such as a List<NewsItem>.
- Displaying News Articles:

Bind the list of news articles to the UI component (ListView/RecyclerView) to populate the view with the retrieved data.
Customize the item layout to display the relevant information, including the article title, description, and thumbnail image.
Handle user interaction events, such as tapping on a news article to open the full article or view more details.
- Periodic Content Updates:

To provide weekly or fortnightly updates, And It is needed to trigger the news data fetching periodically.
Schedule background tasks or use services like Firebase Cloud Messaging (FCM) to notify the app about new content availability.
Update the news data in the app's storage and refresh the UI accordingly.
- Caching and Offline Support:

Implement a caching mechanism to store previously fetched news articles on the device.
Consider using technologies like SQLite, Realm, or Xamarin.Essentials Preferences for local storage.
Enable offline support by allowing users to access previously loaded news articles when there is no internet connection.
- Error Handling and Exceptional Cases:

Implement appropriate error handling mechanisms to handle cases such as network failures, server errors, or parsing issues.
Show relevant error messages or fallback content when news data cannot be retrieved.
Provide an option for users to refresh the news section manually if necessary.

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
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand All @@ -16,7 +16,7 @@
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<TargetFrameworkVersion>v13.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v12.0</TargetFrameworkVersion>
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
<AndroidUseAapt2>true</AndroidUseAapt2>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
Expand Down Expand Up @@ -92,5 +92,5 @@
<Name>UndoAssessment</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>
3 changes: 2 additions & 1 deletion UndoAssessment/UndoAssessment/AppShell.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:UndoAssessment.Views"
Expand Down Expand Up @@ -30,6 +30,7 @@
</Shell.Resources>

<TabBar>
<ShellContent Title="ForCate" Icon="icon_about.png" Route="CatePage" ContentTemplate="{DataTemplate local:CatePage}" />
<ShellContent Title="About" Icon="icon_about.png" Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
<ShellContent Title="Browse" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:ItemsPage}" />
</TabBar>
Expand Down
2 changes: 2 additions & 0 deletions UndoAssessment/UndoAssessment/AppShell.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public partial class AppShell : Xamarin.Forms.Shell
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(CatePage), typeof(CatePage));
Routing.RegisterRoute(nameof(UserFormPage), typeof(UserFormPage));
Routing.RegisterRoute(nameof(ItemDetailPage), typeof(ItemDetailPage));
Routing.RegisterRoute(nameof(NewItemPage), typeof(NewItemPage));
}
Expand Down
22 changes: 22 additions & 0 deletions UndoAssessment/UndoAssessment/Models/ApiResponseModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace UndoAssessment.Models
{
public class ApiResponseModel
{
public string message { get; set; }
public string date { get; set; }
public int errorCode { get; set; }

public bool IsSuccess
{
get
{
return errorCode == 0;
}
}

}
}
12 changes: 12 additions & 0 deletions UndoAssessment/UndoAssessment/Models/UserModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace UndoAssessment.Models
{
public class UserModel
{
public String Name { get; set; }
public String Age { get; set; }
}
}
38 changes: 38 additions & 0 deletions UndoAssessment/UndoAssessment/Services/ApiService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UndoAssessment.Models;

namespace UndoAssessment.Services
{
public class ApiService
{
private static readonly String baseUrl = "https://malkarakundostagingpublicapi.azurewebsites.net/";
private static readonly String success = baseUrl + "success";
private static readonly String fail = baseUrl + "fail";

private static readonly HttpClient httpClient = new HttpClient();

public static async Task<ApiResponseModel> GetSuccess()
{
return await httpRequest(success);
}

public static async Task<ApiResponseModel> GetFail()
{
return await httpRequest(fail);
}

private static async Task<ApiResponseModel> httpRequest(string endpoint)
{
HttpResponseMessage response = await httpClient.GetAsync(endpoint);
String content = await response.Content.ReadAsStringAsync();

return JsonConvert.DeserializeObject<ApiResponseModel>(content);
}
}
}
2 changes: 2 additions & 0 deletions UndoAssessment/UndoAssessment/Services/IDataStore.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UndoAssessment.Models;

namespace UndoAssessment.Services
{
Expand All @@ -11,6 +12,7 @@ public interface IDataStore<T>
Task<bool> DeleteItemAsync(string id);
Task<T> GetItemAsync(string id);
Task<IEnumerable<T>> GetItemsAsync(bool forceRefresh = false);
UserModel User { get; set; }
}
}

9 changes: 9 additions & 0 deletions UndoAssessment/UndoAssessment/Services/MockDataStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,14 @@ public async Task<IEnumerable<Item>> GetItemsAsync(bool forceRefresh = false)
{
return await Task.FromResult(items);
}

private UserModel user;

public UserModel User
{
get { return user; }
set { user = value; }
}

}
}
5 changes: 4 additions & 1 deletion UndoAssessment/UndoAssessment/UndoAssessment.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
<ProduceReferenceAssemblyInOutDir>true</ProduceReferenceAssemblyInOutDir>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</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>
</Project>
113 changes: 113 additions & 0 deletions UndoAssessment/UndoAssessment/ViewModels/CateViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Threading.Tasks;

using UndoAssessment.Models;
using UndoAssessment.Services;
using UndoAssessment.Views;

namespace UndoAssessment.ViewModels
{
public class CateViewModel : BaseViewModel
{

#region Contructor

public CateViewModel()
{
Title = "Assessment for Cate";

PopupUserInfoCommand = new Command(OnPopupUserInfoClicked);
ApiSuccessCommand = new Command(OnApiSuccessClicked);
ApiFailCommand = new Command(OnApiFailClicked);
}

#endregion

#region Functions

public void OnAppearing()
{
OnPropertyChanged(nameof(User));
OnPropertyChanged(nameof(UserVisible));
}

public bool UserVisible
{
get
{
return user != null;
}
}

#endregion

#region Variables

private UserModel user => DataStore.User;

public String User
{
get
{
return user == null
? ""
: $"Name: {user.Name}\n" + $"Age: {user.Age}";
}
}


#endregion

#region Commands

public ICommand OpenWebCommand { get; }

public Command PopupUserInfoCommand { get; }
public Command ApiSuccessCommand { get; }
public Command ApiFailCommand { get; }

private readonly String successText = "Success API";
private readonly String failureText = "Failure API";
private readonly String cancelText = "Cancel";

private void OnPopupUserInfoClicked()
{
Shell.Current.GoToAsync(nameof(UserFormPage));
}

private async void AlertResult(ApiResponseModel resp)
{
if (resp.IsSuccess)
{
await Application.Current.MainPage.DisplayAlert(successText, resp.message, cancelText);
}
else
{
await Application.Current.MainPage.DisplayAlert(failureText, resp.message, cancelText);
}
}

private async void OnApiSuccessClicked()
{
ApiResponseModel resp = await ApiService.GetSuccess();
AlertResult(resp);
}

private async void OnApiFailClicked()
{
ApiResponseModel resp = await ApiService.GetFail();
AlertResult(resp);
}

#endregion

}
}
Loading