Adding final project to dev branch
This commit is contained in:
92
README.md
Normal file
92
README.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# C971 Mobile Application Development Using C Sharp
|
||||
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||
|
||||
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||
|
||||
## Add your files
|
||||
|
||||
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin https://gitlab.com/wgu-gitlab-environment/task-templates/c971-mobile-application-development-using-c-sharp.git
|
||||
git branch -M main
|
||||
git push -uf origin main
|
||||
```
|
||||
|
||||
## Integrate with your tools
|
||||
|
||||
- [ ] [Set up project integrations](https://gitlab.com/wgu-gitlab-environment/task-templates/c971-mobile-application-development-using-c-sharp/-/settings/integrations)
|
||||
|
||||
## Collaborate with your team
|
||||
|
||||
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||
|
||||
## Test and Deploy
|
||||
|
||||
Use the built-in continuous integration in GitLab.
|
||||
|
||||
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||
|
||||
***
|
||||
|
||||
# Editing this README
|
||||
|
||||
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||
|
||||
## Suggestions for a good README
|
||||
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||
|
||||
## Name
|
||||
Choose a self-explaining name for your project.
|
||||
|
||||
## Description
|
||||
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||
|
||||
## Badges
|
||||
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||
|
||||
## Visuals
|
||||
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||
|
||||
## Installation
|
||||
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||
|
||||
## Usage
|
||||
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||
|
||||
## Support
|
||||
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||
|
||||
## Roadmap
|
||||
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||
|
||||
## Contributing
|
||||
State if you are open to contributions and what your requirements are for accepting them.
|
||||
|
||||
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||
|
||||
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||
|
||||
## Authors and acknowledgment
|
||||
Show your appreciation to those who have contributed to the project.
|
||||
|
||||
## License
|
||||
For open source projects, say how it is licensed.
|
||||
|
||||
## Project status
|
||||
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
||||
3
WguApp/.gitignore
vendored
Normal file
3
WguApp/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
bin/
|
||||
obj/
|
||||
.idea/
|
||||
0
WguApp/.noai
Normal file
0
WguApp/.noai
Normal file
14
WguApp/App.xaml
Normal file
14
WguApp/App.xaml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version = "1.0" encoding = "UTF-8" ?>
|
||||
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:WguApp"
|
||||
x:Class="WguApp.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
|
||||
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
25
WguApp/App.xaml.cs
Normal file
25
WguApp/App.xaml.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using WguApp.Services;
|
||||
using WguApp.Views;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
|
||||
private HomePage _homePage = new();
|
||||
private NavigationPage _navPage;
|
||||
|
||||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (Current != null) Current.UserAppTheme = AppTheme.Dark;
|
||||
|
||||
_navPage = new NavigationPage(_homePage);
|
||||
}
|
||||
|
||||
protected override Window CreateWindow(IActivationState? activationState)
|
||||
{
|
||||
return new Window(_navPage);
|
||||
}
|
||||
}
|
||||
29
WguApp/Controls/CustomButton.xaml
Normal file
29
WguApp/Controls/CustomButton.xaml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="WguApp.Controls.CustomButton"
|
||||
x:Name="ThisControl">
|
||||
<Border>
|
||||
<Grid BackgroundColor="#002f51"
|
||||
Padding="10"
|
||||
ColumnDefinitions="*, Auto">
|
||||
|
||||
<Grid.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="TapGestureRecognizer_OnTapped" NumberOfTapsRequired="1" />
|
||||
</Grid.GestureRecognizers>
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="{Binding Text, Source={x:Reference ThisControl}}"
|
||||
FontSize="15"
|
||||
VerticalOptions="Center"
|
||||
TextColor="AliceBlue"
|
||||
HorizontalOptions="Start"/>
|
||||
|
||||
<Label Grid.Column="1"
|
||||
Text="{Binding DateText, Source={x:Reference ThisControl}}"
|
||||
FontSize="12"
|
||||
VerticalOptions="Center"
|
||||
TextColor="Gray"
|
||||
Margin="10,0,0,0"/> </Grid>
|
||||
</Border>
|
||||
</ContentView>
|
||||
51
WguApp/Controls/CustomButton.xaml.cs
Normal file
51
WguApp/Controls/CustomButton.xaml.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WguApp.Controls;
|
||||
|
||||
public partial class CustomButton : ContentView
|
||||
{
|
||||
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public static readonly BindableProperty TextProperty =
|
||||
BindableProperty.Create(
|
||||
propertyName: nameof(Text),
|
||||
returnType: typeof(string),
|
||||
declaringType: typeof(CustomButton),
|
||||
defaultValue: "Text",
|
||||
defaultBindingMode: BindingMode.OneWay);
|
||||
|
||||
public static readonly BindableProperty DateTextProperty =
|
||||
BindableProperty.Create(
|
||||
propertyName: nameof(DateText),
|
||||
returnType: typeof(string),
|
||||
declaringType: typeof(CustomButton),
|
||||
defaultValue: "//",
|
||||
defaultBindingMode: BindingMode.OneWay);
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => (string)GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public string DateText
|
||||
{
|
||||
get => (string)GetValue(DateTextProperty);
|
||||
set => SetValue(DateTextProperty, value);
|
||||
}
|
||||
|
||||
public CustomButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void TapGestureRecognizer_OnTapped(object? sender, TappedEventArgs e)
|
||||
{
|
||||
Clicked?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
2
WguApp/GlobalXmlns.cs
Normal file
2
WguApp/GlobalXmlns.cs
Normal file
@@ -0,0 +1,2 @@
|
||||
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/maui/global", "WguApp")]
|
||||
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/maui/global", "WguApp.Pages")]
|
||||
28
WguApp/MauiProgram.cs
Normal file
28
WguApp/MauiProgram.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Plugin.LocalNotification;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
public static class MauiProgram
|
||||
{
|
||||
public static MauiApp CreateMauiApp()
|
||||
{
|
||||
var builder = MauiApp.CreateBuilder();
|
||||
builder
|
||||
.UseMauiApp<App>()
|
||||
.ConfigureFonts(fonts =>
|
||||
{
|
||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
||||
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
|
||||
fonts.AddFont("Phosphor.ttf", "Phosphor");
|
||||
fonts.AddFont("Phosphor-Fill.ttf", "Phosphor-Fill");
|
||||
})
|
||||
.UseLocalNotification();
|
||||
|
||||
#if DEBUG
|
||||
builder.Logging.AddDebug();
|
||||
#endif
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
25
WguApp/Models/Assessment.cs
Normal file
25
WguApp/Models/Assessment.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using SQLite;
|
||||
|
||||
namespace WguApp.Models;
|
||||
|
||||
[Table("Assessments")]
|
||||
public class Assessment
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
public int CourseId { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public AssessmentType Type { get; set; }
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public bool StartNotifCheck { get; set; } = false;
|
||||
public int StartNotifId { get; set; }
|
||||
public bool EndNotifCheck { get; set; } = false;
|
||||
public int EndNotifId { get; set; }
|
||||
}
|
||||
|
||||
public enum AssessmentType
|
||||
{
|
||||
Performance, Objective
|
||||
}
|
||||
42
WguApp/Models/Course.cs
Normal file
42
WguApp/Models/Course.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using SQLite;
|
||||
|
||||
namespace WguApp.Models;
|
||||
|
||||
[SQLite.Table("Courses")]
|
||||
public class Course
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
public int TermId { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public CourseStatus Status { get; set; }
|
||||
public string InstructorName { get; set; } = string.Empty;
|
||||
public string InstructorPhone { get; set; } = string.Empty;
|
||||
public string InstructorEmail { get; set; } = string.Empty;
|
||||
public bool StartNotifCheck { get; set; } = false;
|
||||
public int StartNotifId { get; set; }
|
||||
public bool EndNotifCheck { get; set; } = false;
|
||||
public int EndNotifId { get; set; }
|
||||
public string Notes { get; set; } = string.Empty;
|
||||
|
||||
public Course() { }
|
||||
public Course(int termId, string name, DateTime startDate, DateTime endDate, CourseStatus status, string instructorName, string instructorPhone, string instructorEmail)
|
||||
{
|
||||
TermId = termId;
|
||||
Name = name;
|
||||
StartDate = startDate;
|
||||
EndDate = endDate;
|
||||
Status = status;
|
||||
InstructorName = instructorName;
|
||||
InstructorPhone = instructorPhone;
|
||||
InstructorEmail = instructorEmail;
|
||||
}
|
||||
}
|
||||
|
||||
public enum CourseStatus
|
||||
{
|
||||
InProgress, Completed, Dropped, Planned
|
||||
}
|
||||
22
WguApp/Models/Term.cs
Normal file
22
WguApp/Models/Term.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using SQLite;
|
||||
|
||||
namespace WguApp.Models;
|
||||
|
||||
[Table("Terms")]
|
||||
public class Term
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public DateTime StartDate {get; set;}
|
||||
public DateTime EndDate {get; set;}
|
||||
|
||||
|
||||
public Term() { }
|
||||
public Term(string name, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
Name = name;
|
||||
StartDate = startDate;
|
||||
EndDate = endDate;
|
||||
}
|
||||
}
|
||||
15
WguApp/Platforms/Android/AndroidManifest.xml
Normal file
15
WguApp/Platforms/Android/AndroidManifest.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<!-- Optional: For exact timing -->
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:maxSdkVersion="32" />
|
||||
</manifest>
|
||||
12
WguApp/Platforms/Android/MainActivity.cs
Normal file
12
WguApp/Platforms/Android/MainActivity.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop,
|
||||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
|
||||
ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
|
||||
public class MainActivity : MauiAppCompatActivity
|
||||
{
|
||||
}
|
||||
15
WguApp/Platforms/Android/MainApplication.cs
Normal file
15
WguApp/Platforms/Android/MainApplication.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Android.App;
|
||||
using Android.Runtime;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
[Application]
|
||||
public class MainApplication : MauiApplication
|
||||
{
|
||||
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
|
||||
: base(handle, ownership)
|
||||
{
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
6
WguApp/Platforms/Android/Resources/values/colors.xml
Normal file
6
WguApp/Platforms/Android/Resources/values/colors.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#512BD4</color>
|
||||
<color name="colorPrimaryDark">#2B0B98</color>
|
||||
<color name="colorAccent">#2B0B98</color>
|
||||
</resources>
|
||||
9
WguApp/Platforms/MacCatalyst/AppDelegate.cs
Normal file
9
WguApp/Platforms/MacCatalyst/AppDelegate.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Foundation;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
14
WguApp/Platforms/MacCatalyst/Entitlements.plist
Normal file
14
WguApp/Platforms/MacCatalyst/Entitlements.plist
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
|
||||
<dict>
|
||||
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
38
WguApp/Platforms/MacCatalyst/Info.plist
Normal file
38
WguApp/Platforms/MacCatalyst/Info.plist
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- The Mac App Store requires you specify if the app uses encryption. -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
|
||||
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
|
||||
<!-- Please indicate <true/> or <false/> here. -->
|
||||
|
||||
<!-- Specify the category for your app here. -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
|
||||
<!-- <key>LSApplicationCategoryType</key> -->
|
||||
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
15
WguApp/Platforms/MacCatalyst/Program.cs
Normal file
15
WguApp/Platforms/MacCatalyst/Program.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
16
WguApp/Platforms/Tizen/Main.cs
Normal file
16
WguApp/Platforms/Tizen/Main.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Microsoft.Maui;
|
||||
using Microsoft.Maui.Hosting;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
class Program : MauiApplication
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var app = new Program();
|
||||
app.Run(args);
|
||||
}
|
||||
}
|
||||
15
WguApp/Platforms/Tizen/tizen-manifest.xml
Normal file
15
WguApp/Platforms/Tizen/tizen-manifest.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="maui-application-id-placeholder" version="0.0.0" api-version="9" xmlns="http://tizen.org/ns/packages">
|
||||
<profile name="common" />
|
||||
<ui-application appid="maui-application-id-placeholder" exec="WguApp.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
|
||||
<label>maui-application-title-placeholder</label>
|
||||
<icon>maui-appicon-placeholder</icon>
|
||||
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
|
||||
</ui-application>
|
||||
<shortcut-list />
|
||||
<privileges>
|
||||
<privilege>http://tizen.org/privilege/internet</privilege>
|
||||
</privileges>
|
||||
<dependencies />
|
||||
<provides-appdefined-privileges />
|
||||
</manifest>
|
||||
8
WguApp/Platforms/Windows/App.xaml
Normal file
8
WguApp/Platforms/Windows/App.xaml
Normal file
@@ -0,0 +1,8 @@
|
||||
<maui:MauiWinUIApplication
|
||||
x:Class="WguApp.WinUI.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:maui="using:Microsoft.Maui"
|
||||
xmlns:local="using:WguApp.WinUI">
|
||||
|
||||
</maui:MauiWinUIApplication>
|
||||
23
WguApp/Platforms/Windows/App.xaml.cs
Normal file
23
WguApp/Platforms/Windows/App.xaml.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace WguApp.WinUI;
|
||||
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
public partial class App : MauiWinUIApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
46
WguApp/Platforms/Windows/Package.appxmanifest
Normal file
46
WguApp/Platforms/Windows/Package.appxmanifest
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
IgnorableNamespaces="uap rescap">
|
||||
|
||||
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="55663ABF-8FF6-41C6-A96E-913924D6F7A4" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>$placeholder$</DisplayName>
|
||||
<PublisherDisplayName>User Name</PublisherDisplayName>
|
||||
<Logo>$placeholder$.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
|
||||
<uap:VisualElements
|
||||
DisplayName="$placeholder$"
|
||||
Description="$placeholder$"
|
||||
Square150x150Logo="$placeholder$.png"
|
||||
Square44x44Logo="$placeholder$.png"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Square71x71Logo="$placeholder$.png" Wide310x150Logo="$placeholder$.png" Square310x310Logo="$placeholder$.png" />
|
||||
<uap:SplashScreen Image="$placeholder$.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
</Capabilities>
|
||||
|
||||
</Package>
|
||||
15
WguApp/Platforms/Windows/app.manifest
Normal file
15
WguApp/Platforms/Windows/app.manifest
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="WguApp.WinUI.app"/>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<!-- The combination of below two tags have the following effect:
|
||||
1) Per-Monitor for >= Windows 10 Anniversary Update
|
||||
2) System < Windows 10 Anniversary Update
|
||||
-->
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
9
WguApp/Platforms/iOS/AppDelegate.cs
Normal file
9
WguApp/Platforms/iOS/AppDelegate.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Foundation;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
32
WguApp/Platforms/iOS/Info.plist
Normal file
32
WguApp/Platforms/iOS/Info.plist
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
15
WguApp/Platforms/iOS/Program.cs
Normal file
15
WguApp/Platforms/iOS/Program.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace WguApp;
|
||||
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
51
WguApp/Platforms/iOS/Resources/PrivacyInfo.xcprivacy
Normal file
51
WguApp/Platforms/iOS/Resources/PrivacyInfo.xcprivacy
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This is the minimum required version of the Apple Privacy Manifest for .NET MAUI apps.
|
||||
The contents below are needed because of APIs that are used in the .NET framework and .NET MAUI SDK.
|
||||
|
||||
You are responsible for adding extra entries as needed for your application.
|
||||
|
||||
More information: https://aka.ms/maui-privacy-manifest
|
||||
-->
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>E174.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<!--
|
||||
The entry below is only needed when you're using the Preferences API in your app.
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict> -->
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
8
WguApp/Properties/launchSettings.json
Normal file
8
WguApp/Properties/launchSettings.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Windows Machine": {
|
||||
"commandName": "Project",
|
||||
"nativeDebugging": false
|
||||
}
|
||||
}
|
||||
}
|
||||
4
WguApp/Resources/AppIcon/appicon.svg
Normal file
4
WguApp/Resources/AppIcon/appicon.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="456" height="456" fill="#512BD4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 228 B |
8
WguApp/Resources/AppIcon/appiconfg.svg
Normal file
8
WguApp/Resources/AppIcon/appiconfg.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
BIN
WguApp/Resources/Fonts/OpenSans-Regular.ttf
Normal file
BIN
WguApp/Resources/Fonts/OpenSans-Regular.ttf
Normal file
Binary file not shown.
BIN
WguApp/Resources/Fonts/OpenSans-Semibold.ttf
Normal file
BIN
WguApp/Resources/Fonts/OpenSans-Semibold.ttf
Normal file
Binary file not shown.
BIN
WguApp/Resources/Fonts/Phosphor-Fill.ttf
Normal file
BIN
WguApp/Resources/Fonts/Phosphor-Fill.ttf
Normal file
Binary file not shown.
BIN
WguApp/Resources/Fonts/Phosphor.ttf
Normal file
BIN
WguApp/Resources/Fonts/Phosphor.ttf
Normal file
Binary file not shown.
BIN
WguApp/Resources/Images/dotnet_bot.png
Normal file
BIN
WguApp/Resources/Images/dotnet_bot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
15
WguApp/Resources/Raw/AboutAssets.txt
Normal file
15
WguApp/Resources/Raw/AboutAssets.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
Any raw assets you want to be deployed with your application can be placed in
|
||||
this directory (and child directories). Deployment of the asset to your application
|
||||
is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
|
||||
|
||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
|
||||
These files will be deployed with your package and will be accessible using Essentials:
|
||||
|
||||
async Task LoadMauiAsset()
|
||||
{
|
||||
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
|
||||
using var reader = new StreamReader(stream);
|
||||
|
||||
var contents = reader.ReadToEnd();
|
||||
}
|
||||
8
WguApp/Resources/Splash/splash.svg
Normal file
8
WguApp/Resources/Splash/splash.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
45
WguApp/Resources/Styles/Colors.xaml
Normal file
45
WguApp/Resources/Styles/Colors.xaml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xaml-comp compile="true" ?>
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
|
||||
|
||||
<!-- Note: For Android please see also Platforms\Android\Resources\values\colors.xml -->
|
||||
|
||||
<Color x:Key="Primary">#512BD4</Color>
|
||||
<Color x:Key="PrimaryDark">#ac99ea</Color>
|
||||
<Color x:Key="PrimaryDarkText">#242424</Color>
|
||||
<Color x:Key="Secondary">#DFD8F7</Color>
|
||||
<Color x:Key="SecondaryDarkText">#9880e5</Color>
|
||||
<Color x:Key="Tertiary">#2B0B98</Color>
|
||||
|
||||
<Color x:Key="White">White</Color>
|
||||
<Color x:Key="Black">Black</Color>
|
||||
<Color x:Key="Magenta">#D600AA</Color>
|
||||
<Color x:Key="MidnightBlue">#190649</Color>
|
||||
<Color x:Key="OffBlack">#1f1f1f</Color>
|
||||
|
||||
<Color x:Key="Gray100">#E1E1E1</Color>
|
||||
<Color x:Key="Gray200">#C8C8C8</Color>
|
||||
<Color x:Key="Gray300">#ACACAC</Color>
|
||||
<Color x:Key="Gray400">#919191</Color>
|
||||
<Color x:Key="Gray500">#6E6E6E</Color>
|
||||
<Color x:Key="Gray600">#404040</Color>
|
||||
<Color x:Key="Gray900">#212121</Color>
|
||||
<Color x:Key="Gray950">#141414</Color>
|
||||
|
||||
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"/>
|
||||
<SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource Secondary}"/>
|
||||
<SolidColorBrush x:Key="TertiaryBrush" Color="{StaticResource Tertiary}"/>
|
||||
<SolidColorBrush x:Key="WhiteBrush" Color="{StaticResource White}"/>
|
||||
<SolidColorBrush x:Key="BlackBrush" Color="{StaticResource Black}"/>
|
||||
|
||||
<SolidColorBrush x:Key="Gray100Brush" Color="{StaticResource Gray100}"/>
|
||||
<SolidColorBrush x:Key="Gray200Brush" Color="{StaticResource Gray200}"/>
|
||||
<SolidColorBrush x:Key="Gray300Brush" Color="{StaticResource Gray300}"/>
|
||||
<SolidColorBrush x:Key="Gray400Brush" Color="{StaticResource Gray400}"/>
|
||||
<SolidColorBrush x:Key="Gray500Brush" Color="{StaticResource Gray500}"/>
|
||||
<SolidColorBrush x:Key="Gray600Brush" Color="{StaticResource Gray600}"/>
|
||||
<SolidColorBrush x:Key="Gray900Brush" Color="{StaticResource Gray900}"/>
|
||||
<SolidColorBrush x:Key="Gray950Brush" Color="{StaticResource Gray950}"/>
|
||||
</ResourceDictionary>
|
||||
440
WguApp/Resources/Styles/Styles.xaml
Normal file
440
WguApp/Resources/Styles/Styles.xaml
Normal file
@@ -0,0 +1,440 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xaml-comp compile="true" ?>
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
|
||||
|
||||
<Style TargetType="ActivityIndicator">
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="IndicatorView">
|
||||
<Setter Property="IndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}"/>
|
||||
<Setter Property="SelectedIndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray100}}"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Stroke" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="StrokeShape" Value="Rectangle"/>
|
||||
<Setter Property="StrokeThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="BoxView">
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource PrimaryDarkText}}" />
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="BorderWidth" Value="0"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="14,10"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="DatePicker">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Editor">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Entry">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ImageButton">
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
<Setter Property="BorderColor" Value="Transparent"/>
|
||||
<Setter Property="BorderWidth" Value="0"/>
|
||||
<Setter Property="CornerRadius" Value="0"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label" x:Key="Headline">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontSize" Value="32" />
|
||||
<Setter Property="HorizontalOptions" Value="Center" />
|
||||
<Setter Property="HorizontalTextAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label" x:Key="SubHeadline">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontSize" Value="24" />
|
||||
<Setter Property="HorizontalOptions" Value="Center" />
|
||||
<Setter Property="HorizontalTextAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ListView">
|
||||
<Setter Property="SeparatorColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="RefreshControlColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Picker">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ProgressBar">
|
||||
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="RadioButton">
|
||||
<Setter Property="BackgroundColor" Value="Transparent"/>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="RefreshView">
|
||||
<Setter Property="RefreshColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SearchBar">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="CancelButtonColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SearchHandler">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Shadow">
|
||||
<Setter Property="Radius" Value="15" />
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
<Setter Property="Brush" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Offset" Value="10,10" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Slider">
|
||||
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
|
||||
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SwipeItem">
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Switch">
|
||||
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="ThumbColor" Value="{StaticResource White}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="On">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Off">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TimePicker">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent"/>
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
<Style TargetType="TitleBar">
|
||||
<Setter Property="MinimumHeightRequest" Value="32"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="TitleActiveStates">
|
||||
<VisualState x:Name="TitleBarTitleActive">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="TitleBarTitleInactive">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
-->
|
||||
|
||||
<Style TargetType="Page" ApplyToDerivedTypes="True">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Shell" ApplyToDerivedTypes="True">
|
||||
<Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
<Setter Property="Shell.ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
|
||||
<Setter Property="Shell.TitleColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
|
||||
<Setter Property="Shell.DisabledColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="Shell.UnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="Shell.NavBarHasShadow" Value="False" />
|
||||
<Setter Property="Shell.TabBarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
<Setter Property="Shell.TabBarForegroundColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Shell.TabBarTitleColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Shell.TabBarUnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="NavigationPage">
|
||||
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
|
||||
<Setter Property="IconColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TabbedPage">
|
||||
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="UnselectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="SelectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
230
WguApp/Services/DatabaseService.cs
Normal file
230
WguApp/Services/DatabaseService.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
|
||||
using SQLite;
|
||||
using WguApp.Models;
|
||||
|
||||
namespace WguApp.Services;
|
||||
|
||||
public static class DatabaseService
|
||||
{
|
||||
|
||||
private static SQLiteAsyncConnection? _db;
|
||||
|
||||
public static async Task Init()
|
||||
{
|
||||
if (_db is not null) return;
|
||||
|
||||
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "WguApp.db");
|
||||
_db = new SQLiteAsyncConnection(databasePath);
|
||||
|
||||
try
|
||||
{
|
||||
await _db.CreateTablesAsync<Term, Course, Assessment>();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Add Methods -- //
|
||||
#region Add methods
|
||||
|
||||
public static async Task<bool> AddTerm(Term term)
|
||||
{
|
||||
await Init();
|
||||
var result = await _db?.InsertAsync(term)!;
|
||||
return !(result <= 0);
|
||||
}
|
||||
|
||||
public static async Task<bool> AddCourse(Course course)
|
||||
{
|
||||
await Init();
|
||||
var result = await _db?.InsertAsync(course)!;
|
||||
return !(result <= 0);
|
||||
}
|
||||
|
||||
public static async Task<bool> AddAssessment(Assessment assessment)
|
||||
{
|
||||
await Init();
|
||||
var result = await _db?.InsertAsync(assessment)!;
|
||||
return !(result <= 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// -- Get Methods -- //
|
||||
#region Get Methods
|
||||
public static async Task<List<Term>> GetAllTerms()
|
||||
{
|
||||
await Init();
|
||||
var allTerms = await _db?.Table<Term>().ToListAsync()!;
|
||||
return allTerms ?? [];
|
||||
}
|
||||
|
||||
public static async Task<List<Course>> GetAllCourses()
|
||||
{
|
||||
await Init();
|
||||
var allCourses = await _db?.Table<Course>().ToListAsync()!;
|
||||
return allCourses ?? [];
|
||||
}
|
||||
|
||||
public static async Task<List<Assessment>> GetAllAssessments()
|
||||
{
|
||||
await Init();
|
||||
var allAssessments = await _db?.Table<Assessment>().ToListAsync()!;
|
||||
return allAssessments ?? [];
|
||||
}
|
||||
|
||||
public static async Task<List<Assessment>> GetAssessmentsByCourseId(int courseId)
|
||||
{
|
||||
await Init();
|
||||
var query = $"SELECT * FROM Assessments WHERE CourseId = {courseId}";
|
||||
var result = await _db?.QueryAsync<Assessment>(query)!;
|
||||
return result.ToList() ?? [];
|
||||
}
|
||||
|
||||
public static async Task<List<Course>> GetCoursesByTermId(int termId)
|
||||
{
|
||||
await Init();
|
||||
var query = $"SELECT * FROM Courses WHERE TermId = {termId}";
|
||||
var result = await _db?.QueryAsync<Course>(query)!;
|
||||
return result.ToList() ?? [];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// -- Update Methods
|
||||
#region Update Methods
|
||||
|
||||
public static async Task<bool> UpdateTerm(Term term)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.UpdateAsync(term)! != 0;
|
||||
}
|
||||
|
||||
public static async Task<bool> UpdateCourse(Course course)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.UpdateAsync(course)! != 0;
|
||||
}
|
||||
|
||||
public static async Task<bool> UpdateAssessment(Assessment assessment)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.UpdateAsync(assessment)! != 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// -- Delete Methods
|
||||
#region Delete Methods
|
||||
public static async Task<bool> DeleteTerm(Term term)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.DeleteAsync(term)! != 0;
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteTerm(int termId)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.DeleteAsync<Term>(termId)! != 0;
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteCourse(Course course)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.DeleteAsync(course)! != 0;
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteCourse(int courseId)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.DeleteAsync<Course>(courseId)! != 0;
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteAssessment(Assessment assessment)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.DeleteAsync(assessment)! != 0;
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteAssessment(int assessmentId)
|
||||
{
|
||||
await Init();
|
||||
return await _db?.DeleteAsync<Assessment>(assessmentId)! != 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
// -- Sample Data -- //
|
||||
public static async Task LoadSampleData()
|
||||
{
|
||||
await ClearDbData();
|
||||
|
||||
var term1 = new Term()
|
||||
{
|
||||
Name = "Term 1",
|
||||
StartDate = DateTime.Today,
|
||||
EndDate = DateTime.Today.AddDays(30)
|
||||
};
|
||||
|
||||
await AddTerm(term1);
|
||||
|
||||
var course1 = new Course()
|
||||
{
|
||||
TermId = term1.Id,
|
||||
Name = "Course 1",
|
||||
StartDate = DateTime.Today,
|
||||
EndDate = DateTime.Today.AddDays(30),
|
||||
InstructorName = "Anika Patel",
|
||||
InstructorEmail = "anika.patel@strimeuniversity.edu",
|
||||
InstructorPhone = "555-123-4567",
|
||||
StartNotifCheck = false,
|
||||
EndNotifCheck = false,
|
||||
Status = CourseStatus.InProgress,
|
||||
Notes = "Some notes"
|
||||
};
|
||||
|
||||
await AddCourse(course1);
|
||||
|
||||
var assessment1 = new Assessment()
|
||||
{
|
||||
CourseId = course1.Id,
|
||||
Name = "Performance Assessment",
|
||||
Type = AssessmentType.Performance,
|
||||
StartDate = DateTime.Today,
|
||||
EndDate = DateTime.Today.AddDays(30),
|
||||
StartNotifCheck = false,
|
||||
EndNotifCheck = false
|
||||
};
|
||||
|
||||
await AddAssessment(assessment1);
|
||||
|
||||
var assessment2 = new Assessment()
|
||||
{
|
||||
CourseId = course1.Id,
|
||||
Name = "Objective Assessment",
|
||||
Type = AssessmentType.Objective,
|
||||
StartDate = DateTime.Today,
|
||||
EndDate = DateTime.Today.AddDays(30),
|
||||
StartNotifCheck = false,
|
||||
EndNotifCheck = false
|
||||
};
|
||||
|
||||
await AddAssessment(assessment2);
|
||||
}
|
||||
|
||||
public static async Task ClearDbData()
|
||||
{
|
||||
await Init();
|
||||
|
||||
await _db?.DeleteAllAsync<Assessment>()!;
|
||||
await _db?.DeleteAllAsync<Course>()!;
|
||||
await _db?.DeleteAllAsync<Term>()!;
|
||||
|
||||
_db = null;
|
||||
|
||||
}
|
||||
}
|
||||
114
WguApp/Services/LocalNotificationService.cs
Normal file
114
WguApp/Services/LocalNotificationService.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using Plugin.LocalNotification;
|
||||
|
||||
namespace WguApp.Services;
|
||||
|
||||
public static class LocalNotificationService
|
||||
{
|
||||
private static readonly Random Rng = new();
|
||||
|
||||
public static async Task<int?> ScheduleNotification(string title, string description, DateTime time)
|
||||
{
|
||||
var permCheck = await PermissionsService.CheckNotificationPermissions();
|
||||
if (!permCheck)
|
||||
{
|
||||
LoggerService.LogToFile("Notification Service: Notification Permission Not Granted");
|
||||
return null;
|
||||
}
|
||||
|
||||
var newId = Rng.Next();
|
||||
|
||||
var notif = new NotificationRequest
|
||||
{
|
||||
NotificationId = newId,
|
||||
Title = title,
|
||||
Description = description,
|
||||
Schedule =
|
||||
{
|
||||
NotifyTime = time,
|
||||
RepeatType = NotificationRepeat.No
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await LocalNotificationCenter.Current.Show(notif);
|
||||
LoggerService.LogToFile($"Notification Service: {notif.NotificationId}:{notif.Title} set");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LoggerService.LogToFile($"Notification Service: {e.Message}");
|
||||
throw;
|
||||
}
|
||||
|
||||
return notif.NotificationId;
|
||||
}
|
||||
|
||||
public static async Task<int> ScheduleNotification(NotificationRequest notif)
|
||||
{
|
||||
try
|
||||
{
|
||||
await LocalNotificationCenter.Current.Show(notif);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LoggerService.LogToFile(e.Message);
|
||||
throw;
|
||||
}
|
||||
return notif.NotificationId;
|
||||
}
|
||||
|
||||
public static async Task<bool> UpdateNotification(int notificationId, string? title = null, string? description = null, DateTime? time = null)
|
||||
{
|
||||
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
|
||||
|
||||
var notif = pendingNotifs.FirstOrDefault(n => n.NotificationId == notificationId);
|
||||
|
||||
if (notif is null) return false;
|
||||
|
||||
await CancelNotification(notif);
|
||||
|
||||
notif.Title = title ?? notif.Title;
|
||||
notif.Description = description ?? notif.Description;
|
||||
notif.Schedule = new NotificationRequestSchedule()
|
||||
{
|
||||
NotifyTime = time ?? notif.Schedule.NotifyTime,
|
||||
RepeatType = NotificationRepeat.No
|
||||
};
|
||||
|
||||
await ScheduleNotification(notif);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async Task<bool> CancelNotification(int notificationId)
|
||||
{
|
||||
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
|
||||
|
||||
var match = pendingNotifs.FirstOrDefault(n => n.NotificationId == notificationId);
|
||||
|
||||
if (match is null) return false;
|
||||
|
||||
LocalNotificationCenter.Current.Cancel(notificationId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async Task<bool> CancelNotification(NotificationRequest notif)
|
||||
{
|
||||
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
|
||||
|
||||
if (pendingNotifs.Contains(notif))
|
||||
{
|
||||
notif.Cancel();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async Task<bool> DoesNotificationAlreadyExist(int notificationId)
|
||||
{
|
||||
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
|
||||
var match = pendingNotifs.FirstOrDefault(n => n.NotificationId == notificationId);
|
||||
|
||||
return match is not null;
|
||||
}
|
||||
}
|
||||
11
WguApp/Services/LoggerService.cs
Normal file
11
WguApp/Services/LoggerService.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace WguApp.Services;
|
||||
|
||||
public class LoggerService
|
||||
{
|
||||
public static void LogToFile(string text)
|
||||
{
|
||||
var logFilePath = Path.Combine(FileSystem.AppDataDirectory, "log.txt");
|
||||
|
||||
File.AppendAllText(logFilePath, $"{DateTime.UtcNow} : {text}\n");
|
||||
}
|
||||
}
|
||||
21
WguApp/Services/PermissionsService.cs
Normal file
21
WguApp/Services/PermissionsService.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Plugin.LocalNotification;
|
||||
|
||||
namespace WguApp.Services;
|
||||
|
||||
public static class PermissionsService
|
||||
{
|
||||
public static async Task<bool> CheckNotificationPermissions()
|
||||
{
|
||||
if (await LocalNotificationCenter.Current.AreNotificationsEnabled()) return true;
|
||||
|
||||
try
|
||||
{
|
||||
return await LocalNotificationCenter.Current.RequestNotificationPermission();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LoggerService.LogToFile(e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
125
WguApp/Views/AssessmentPage.xaml
Normal file
125
WguApp/Views/AssessmentPage.xaml
Normal file
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="WguApp.Views.AssessmentPage">
|
||||
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Save"
|
||||
Order="Primary"
|
||||
Priority="0"
|
||||
IconImageSource="{FontImageSource Glyph='', FontFamily='Phosphor', Size=20, Color=AliceBlue}"
|
||||
Clicked="SaveButton_OnClicked"/>
|
||||
<ToolbarItem Text="Delete"
|
||||
Order="Primary"
|
||||
Priority="0"
|
||||
IconImageSource="{FontImageSource Glyph='', FontFamily='Phosphor', Size=20, Color=Red}"
|
||||
Clicked="DeleteButton_OnClicked"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Content>
|
||||
<Grid RowDefinitions="*">
|
||||
<ScrollView HorizontalOptions="Fill"
|
||||
HorizontalScrollBarVisibility="Never">
|
||||
<VerticalStackLayout HorizontalOptions="Fill">
|
||||
|
||||
<Label Text="Assessment Info"
|
||||
FontAttributes="Bold"
|
||||
FontSize="20"
|
||||
Margin="20, 10, 20, 5"/>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, *"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Title:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<Entry x:Name="TitleEntry"
|
||||
Grid.Column="1"
|
||||
Placeholder="Enter value here..."
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Start date:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<DatePicker x:Name="StartDatePicker"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Expected end date:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<DatePicker x:Name="EndDatePicker"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Label Text="Notifications"
|
||||
FontAttributes="Bold"
|
||||
FontSize="20"
|
||||
Margin="20, 5"/>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Start Date:"
|
||||
VerticalOptions="Center" />
|
||||
<CheckBox x:Name="StartNotifCheck"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="End Date:"
|
||||
VerticalOptions="Center" />
|
||||
<CheckBox x:Name="EndNotifCheck"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
137
WguApp/Views/AssessmentPage.xaml.cs
Normal file
137
WguApp/Views/AssessmentPage.xaml.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WguApp.Models;
|
||||
using WguApp.Services;
|
||||
|
||||
namespace WguApp.Views;
|
||||
|
||||
public partial class AssessmentPage : ContentPage
|
||||
{
|
||||
|
||||
private Assessment _assessment;
|
||||
|
||||
public AssessmentPage(Assessment assessment)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_assessment = assessment;
|
||||
|
||||
Title = assessment.Name;
|
||||
|
||||
TitleEntry.Text = _assessment.Name;
|
||||
StartDatePicker.Date = _assessment.StartDate;
|
||||
EndDatePicker.Date = _assessment.EndDate;
|
||||
StartNotifCheck.IsChecked = _assessment.StartNotifCheck;
|
||||
EndNotifCheck.IsChecked = _assessment.EndNotifCheck;
|
||||
|
||||
StartNotifCheck.CheckedChanged += async (sender, e) => { await ToggleStartNotification(); };
|
||||
EndNotifCheck.CheckedChanged += async (sender, e) => { await ToggleEndNotification(); };
|
||||
}
|
||||
|
||||
private async Task ToggleStartNotification()
|
||||
{
|
||||
if (StartNotifCheck.IsChecked)
|
||||
{
|
||||
var id = await LocalNotificationService.ScheduleNotification($"{_assessment.Name} Start Reminder", $"Your assessment '{_assessment.Id} starts in 12 hours'", _assessment.StartDate.Subtract(TimeSpan.FromHours(12)));
|
||||
_assessment.StartNotifId = id ?? 0;
|
||||
LoggerService.LogToFile($"{_assessment.Id}:{_assessment.Name} set start notification {_assessment.StartNotifId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var res = await LocalNotificationService.CancelNotification(_assessment.StartNotifId);
|
||||
LoggerService.LogToFile($"{_assessment.Id}:{_assessment.Name} canceled start notification {_assessment.StartNotifId}");
|
||||
_assessment.StartNotifId = 0;
|
||||
}
|
||||
|
||||
_assessment.StartNotifCheck = StartNotifCheck.IsChecked;
|
||||
}
|
||||
|
||||
private async Task ToggleEndNotification()
|
||||
{
|
||||
if (EndNotifCheck.IsChecked)
|
||||
{
|
||||
var id = await LocalNotificationService.ScheduleNotification($"{_assessment.Name} End Reminder", $"Your assessment '{_assessment.Id} ends in 12 hours'", _assessment.EndDate.Subtract(TimeSpan.FromHours(12)));
|
||||
_assessment.EndNotifId = id ?? 0;
|
||||
LoggerService.LogToFile($"{_assessment.Id}:{_assessment.Name} set end notification {_assessment.EndNotifId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var res = await LocalNotificationService.CancelNotification(_assessment.EndNotifId);
|
||||
LoggerService.LogToFile($"{_assessment.Id}:{_assessment.Name} canceled end notification {_assessment.EndNotifId}");
|
||||
_assessment.EndNotifId = 0;
|
||||
}
|
||||
|
||||
_assessment.EndNotifCheck = EndNotifCheck.IsChecked;
|
||||
}
|
||||
|
||||
private (string msg, bool result) ValidateFields()
|
||||
{
|
||||
var message = string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(TitleEntry.Text)) message += "Title cannot be blank\n";
|
||||
if (StartDatePicker.Date > EndDatePicker.Date) message += "Start Date cannot be after the End Date\n";
|
||||
|
||||
return string.IsNullOrWhiteSpace(message) ? (message, true) : (message, false);
|
||||
}
|
||||
|
||||
private async Task<bool> Save()
|
||||
{
|
||||
var validationResult = ValidateFields();
|
||||
|
||||
if (!validationResult.result)
|
||||
{
|
||||
await DisplayAlert("Validation Error", validationResult.msg, "Ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
_assessment.Name = TitleEntry.Text;
|
||||
_assessment.StartDate = StartDatePicker.Date;
|
||||
_assessment.EndDate = EndDatePicker.Date;
|
||||
_assessment.StartNotifCheck = StartNotifCheck.IsChecked;
|
||||
_assessment.EndNotifCheck = EndNotifCheck.IsChecked;
|
||||
|
||||
var updateResult = await DatabaseService.UpdateAssessment(_assessment);
|
||||
|
||||
if (updateResult)
|
||||
{
|
||||
await DisplayAlert("Info", $"{_assessment.Name} Saved!", "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
await DisplayAlert("Error", "Could not save term", "Ok");
|
||||
}
|
||||
|
||||
Title = _assessment.Name;
|
||||
|
||||
if (_assessment.StartNotifId != 0)
|
||||
{
|
||||
await LocalNotificationService.UpdateNotification(_assessment.StartNotifId, $"{_assessment.Name} Start Reminder",
|
||||
$"Your course '{_assessment.Id} starts in 12 hours'", _assessment.StartDate.Subtract(TimeSpan.FromHours(12)));
|
||||
}
|
||||
|
||||
if (_assessment.EndNotifId != 0)
|
||||
{
|
||||
await LocalNotificationService.UpdateNotification(_assessment.EndNotifId, $"{_assessment.Name} End Reminder",
|
||||
$"Your course '{_assessment.Id} ends in 12 hours'", _assessment.EndDate.Subtract(TimeSpan.FromHours(12)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async void SaveButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
await Save();
|
||||
}
|
||||
|
||||
private async void DeleteButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
var result = await DisplayAlert("Delete Course", $"Do you really want to delete '{_assessment.Name}'? This action cannot be undone.", "Delete", "Cancel");
|
||||
if (!result) return;
|
||||
|
||||
await DatabaseService.DeleteAssessment(_assessment);
|
||||
await Navigation.PopAsync();
|
||||
}
|
||||
}
|
||||
270
WguApp/Views/CoursePage.xaml
Normal file
270
WguApp/Views/CoursePage.xaml
Normal file
@@ -0,0 +1,270 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="WguApp.Views.CoursePage">
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Save"
|
||||
Order="Primary"
|
||||
Priority="0"
|
||||
IconImageSource="{FontImageSource Glyph='', FontFamily='Phosphor', Size=20, Color=AliceBlue}"
|
||||
Clicked="SaveButton_OnClicked"/>
|
||||
<ToolbarItem Text="Delete"
|
||||
Order="Primary"
|
||||
Priority="0"
|
||||
IconImageSource="{FontImageSource Glyph='', FontFamily='Phosphor', Size=20, Color=Red}"
|
||||
Clicked="DeleteButton_OnClicked"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Content>
|
||||
<Grid RowDefinitions="*">
|
||||
<ScrollView HorizontalOptions="Fill"
|
||||
HorizontalScrollBarVisibility="Never">
|
||||
<VerticalStackLayout HorizontalOptions="Fill">
|
||||
<Label Text="Course Info"
|
||||
FontAttributes="Bold"
|
||||
FontSize="20"
|
||||
Margin="20, 10, 20, 5"/>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, *"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Title:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<Entry x:Name="TitleEntry"
|
||||
Grid.Column="1"
|
||||
Placeholder="Enter value here..."
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Start date:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<DatePicker x:Name="StartDatePicker"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Expected end date:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<DatePicker x:Name="EndDatePicker"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Status:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<Picker x:Name="StatusPicker"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Label Text="Instructor"
|
||||
FontAttributes="Bold"
|
||||
FontSize="20"
|
||||
Margin="20, 10, 20, 5"/>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Name:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<Entry x:Name="InstructorNameEntry"
|
||||
Grid.Column="1"
|
||||
Placeholder="Name"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10, 20, 5">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Phone:"
|
||||
VerticalOptions="Center" />
|
||||
|
||||
<Entry x:Name="InstructorPhoneEntry"
|
||||
Grid.Column="1"
|
||||
Placeholder="Phone"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Email:"
|
||||
VerticalOptions="Center" />
|
||||
<Entry x:Name="InstructorEmailEntry"
|
||||
Grid.Column="1"
|
||||
Placeholder="Email"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 5">
|
||||
|
||||
<Label Grid.Column="0" Text="Notes"
|
||||
FontAttributes="Bold"
|
||||
FontSize="20"
|
||||
VerticalOptions="Center"/>
|
||||
|
||||
<Button Grid.Column="1"
|
||||
Text=""
|
||||
FontFamily="Phosphor"
|
||||
FontSize="20"
|
||||
WidthRequest="20"
|
||||
HeightRequest="20"
|
||||
TextColor="AliceBlue"
|
||||
BackgroundColor="Transparent"
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="Center"
|
||||
Clicked="ShareNotesButton_OnClicked"/>
|
||||
</Grid>
|
||||
|
||||
<Border HorizontalOptions="Fill"
|
||||
Margin="30, 5"
|
||||
Stroke="AliceBlue"
|
||||
StrokeThickness="2">
|
||||
<Editor x:Name="NotesEditor"
|
||||
HeightRequest="150"/>
|
||||
</Border>
|
||||
|
||||
<Label Text="Notifications"
|
||||
FontAttributes="Bold"
|
||||
FontSize="20"
|
||||
Margin="20, 5"/>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Start Date:"
|
||||
VerticalOptions="Center" />
|
||||
<CheckBox x:Name="StartNotifCheck"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, Auto"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="End Date:"
|
||||
VerticalOptions="Center" />
|
||||
<CheckBox x:Name="EndNotifCheck"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="End" />
|
||||
</Grid>
|
||||
|
||||
<Grid RowDefinitions="*, Auto"
|
||||
ColumnDefinitions="*, Auto"
|
||||
HorizontalOptions="Fill"
|
||||
HeightRequest="40"
|
||||
Margin="30, 20, 30, 0">
|
||||
|
||||
<Label Text="Assessments"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontSize="15"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Fill"
|
||||
HorizontalTextAlignment="Start"
|
||||
HeightRequest="20" />
|
||||
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Text=""
|
||||
FontFamily="Phosphor"
|
||||
FontSize="15"
|
||||
WidthRequest="20"
|
||||
HeightRequest="20"
|
||||
TextColor="AliceBlue"
|
||||
BackgroundColor="Transparent"
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="Center"
|
||||
Clicked="AddAssessmentButton_OnClicked"/>
|
||||
</Grid>
|
||||
|
||||
<BoxView
|
||||
Color="AliceBlue"
|
||||
HeightRequest="2"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="30, 0, 30, 20" />
|
||||
|
||||
<VerticalStackLayout x:Name="AssessmentButtonStack"
|
||||
Margin="30,10"
|
||||
HorizontalOptions="Fill"
|
||||
Spacing="5"/>
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
264
WguApp/Views/CoursePage.xaml.cs
Normal file
264
WguApp/Views/CoursePage.xaml.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WguApp.Controls;
|
||||
using WguApp.Models;
|
||||
using WguApp.Services;
|
||||
|
||||
namespace WguApp.Views;
|
||||
|
||||
public partial class CoursePage : ContentPage
|
||||
{
|
||||
|
||||
private Course _course;
|
||||
|
||||
private Assessment? _oa = null;
|
||||
private Assessment? _pa = null;
|
||||
|
||||
public CoursePage(Course course)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_course = course;
|
||||
|
||||
Title = _course.Name;
|
||||
|
||||
StatusPicker.ItemsSource = Enum.GetValues<CourseStatus>();
|
||||
|
||||
TitleEntry.Text = _course.Name;
|
||||
StartDatePicker.Date = _course.StartDate;
|
||||
EndDatePicker.Date = _course.EndDate;
|
||||
StatusPicker.SelectedItem = _course.Status;
|
||||
InstructorNameEntry.Text = _course.InstructorName;
|
||||
InstructorEmailEntry.Text = _course.InstructorEmail;
|
||||
InstructorPhoneEntry.Text = _course.InstructorPhone;
|
||||
NotesEditor.Text = _course.Notes;
|
||||
StartNotifCheck.IsChecked = _course.StartNotifCheck;
|
||||
EndNotifCheck.IsChecked = _course.EndNotifCheck;
|
||||
|
||||
StartNotifCheck.CheckedChanged += async (sender, e) => { await ToggleStartNotification(); };
|
||||
EndNotifCheck.CheckedChanged += async (sender, e) => { await ToggleEndNotification(); };
|
||||
}
|
||||
|
||||
private async Task ToggleStartNotification()
|
||||
{
|
||||
if (StartNotifCheck.IsChecked)
|
||||
{
|
||||
var id = await LocalNotificationService.ScheduleNotification($"{_course.Name} Start Reminder", $"Your course '{_course.Id} starts in 12 hours'", _course.StartDate.Subtract(TimeSpan.FromHours(12)));
|
||||
_course.StartNotifId = id ?? 0;
|
||||
LoggerService.LogToFile($"{_course.Id}:{_course.Name} set start notification {_course.StartNotifId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var res = await LocalNotificationService.CancelNotification(_course.StartNotifId);
|
||||
LoggerService.LogToFile($"{_course.Id}:{_course.Name} canceled start notification {_course.StartNotifId}");
|
||||
_course.StartNotifId = 0;
|
||||
}
|
||||
|
||||
_course.StartNotifCheck = StartNotifCheck.IsChecked;
|
||||
}
|
||||
|
||||
private async Task ToggleEndNotification()
|
||||
{
|
||||
if (EndNotifCheck.IsChecked)
|
||||
{
|
||||
var id = await LocalNotificationService.ScheduleNotification($"{_course.Name} End Reminder", $"Your course '{_course.Id} ends in 12 hours'", _course.EndDate.Subtract(TimeSpan.FromHours(12)));
|
||||
_course.EndNotifId = id ?? 0;
|
||||
LoggerService.LogToFile($"{_course.Id}:{_course.Name} set end notification {_course.EndNotifId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var res = await LocalNotificationService.CancelNotification(_course.EndNotifId);
|
||||
LoggerService.LogToFile($"{_course.Id}:{_course.Name} canceled end notification {_course.EndNotifId}");
|
||||
_course.EndNotifId = 0;
|
||||
}
|
||||
|
||||
_course.EndNotifCheck = EndNotifCheck.IsChecked;
|
||||
}
|
||||
|
||||
private (string msg, bool result) ValidateFields()
|
||||
{
|
||||
var message = string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(TitleEntry.Text)) message += "Title cannot be blank\n";
|
||||
if (StartDatePicker.Date > EndDatePicker.Date) message += "Start Date cannot be after the End Date\n";
|
||||
if (string.IsNullOrWhiteSpace(InstructorNameEntry.Text)) message += "Instructor Name cannot be blank\n";
|
||||
if (string.IsNullOrWhiteSpace(InstructorPhoneEntry.Text)) message += "Instructor Phone cannot be blank\n";
|
||||
if (string.IsNullOrWhiteSpace(InstructorEmailEntry.Text)) message += "Instructor Email cannot be blank\n";
|
||||
|
||||
return string.IsNullOrWhiteSpace(message) ? (message, true) : (message, false);
|
||||
}
|
||||
|
||||
private async void SaveButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
await Save();
|
||||
}
|
||||
|
||||
private async Task<bool> Save()
|
||||
{
|
||||
var validationResult = ValidateFields();
|
||||
|
||||
if (!validationResult.result)
|
||||
{
|
||||
await DisplayAlert("Validation Error", validationResult.msg, "Ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
_course.Name = TitleEntry.Text;
|
||||
_course.StartDate = StartDatePicker.Date;
|
||||
_course.EndDate = EndDatePicker.Date;
|
||||
_course.InstructorName = InstructorNameEntry.Text;
|
||||
_course.InstructorPhone = InstructorPhoneEntry.Text;
|
||||
_course.InstructorEmail = InstructorEmailEntry.Text;
|
||||
_course.Notes = NotesEditor.Text;
|
||||
_course.StartNotifCheck = StartNotifCheck.IsChecked;
|
||||
_course.EndNotifCheck = EndNotifCheck.IsChecked;
|
||||
|
||||
var updateResult = await DatabaseService.UpdateCourse(_course);
|
||||
|
||||
if (updateResult)
|
||||
{
|
||||
await DisplayAlert("Info", $"{_course.Name} Saved!", "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
await DisplayAlert("Error", "Could not save term", "Ok");
|
||||
}
|
||||
|
||||
Title = _course.Name;
|
||||
|
||||
if (_course.StartNotifId != 0)
|
||||
{
|
||||
await LocalNotificationService.UpdateNotification(_course.StartNotifId, $"{_course.Name} Start Reminder",
|
||||
$"Your course '{_course.Id} starts in 12 hours'", _course.StartDate.Subtract(TimeSpan.FromHours(12)));
|
||||
}
|
||||
|
||||
if (_course.EndNotifId != 0)
|
||||
{
|
||||
await LocalNotificationService.UpdateNotification(_course.EndNotifId, $"{_course.Name} End Reminder",
|
||||
$"Your course '{_course.Id} ends in 12 hours'", _course.EndDate.Subtract(TimeSpan.FromHours(12)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async void DeleteButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
var result = await DisplayAlert("Delete Course", $"Do you really want to delete '{_course.Name}'? This action cannot be undone.", "Delete", "Cancel");
|
||||
if (!result) return;
|
||||
|
||||
await DatabaseService.DeleteCourse(_course);
|
||||
await Navigation.PopAsync();
|
||||
}
|
||||
|
||||
private async void ShareNotesButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NotesEditor.Text))
|
||||
{
|
||||
await DisplayAlert("Info", "Failed to share: Notes are empty", "Ok");
|
||||
}
|
||||
|
||||
await Share.Default.RequestAsync(new ShareTextRequest
|
||||
{
|
||||
Title = "Share course notes",
|
||||
Text = $"-- Course notes for {_course.Name} --\n{NotesEditor.Text}"
|
||||
});
|
||||
}
|
||||
|
||||
private async Task RefreshAssessmentsList()
|
||||
{
|
||||
AssessmentButtonStack.Children.Clear();
|
||||
|
||||
var allAssessments = await DatabaseService.GetAssessmentsByCourseId(_course.Id);
|
||||
|
||||
_oa = allAssessments.FirstOrDefault(a => a.Type == AssessmentType.Objective);
|
||||
_pa = allAssessments.FirstOrDefault(a => a.Type == AssessmentType.Performance);
|
||||
|
||||
if (_oa is not null)
|
||||
{
|
||||
var oaBtn = new CustomButton()
|
||||
{
|
||||
Text = _oa.Name,
|
||||
DateText = $"{DateOnly.FromDateTime(_oa.StartDate).ToString()} - {DateOnly.FromDateTime(_oa.EndDate).ToString()}"
|
||||
};
|
||||
|
||||
AssessmentButtonStack.Add(oaBtn);
|
||||
|
||||
oaBtn.Clicked += async (sender, e) => { await HandleAssessmentButtonClick(_oa); };
|
||||
}
|
||||
|
||||
if (_pa is not null)
|
||||
{
|
||||
var paBtn = new CustomButton()
|
||||
{
|
||||
Text = _pa.Name,
|
||||
DateText = $"{DateOnly.FromDateTime(_pa.StartDate).ToString()} - {DateOnly.FromDateTime(_pa.EndDate).ToString()}"
|
||||
};
|
||||
|
||||
AssessmentButtonStack.Add(paBtn);
|
||||
|
||||
paBtn.Clicked += async (sender, e) => { await HandleAssessmentButtonClick(_pa); };
|
||||
}
|
||||
}
|
||||
|
||||
protected async override void OnNavigatedTo(NavigatedToEventArgs args)
|
||||
{
|
||||
await RefreshAssessmentsList();
|
||||
}
|
||||
|
||||
private async Task HandleAssessmentButtonClick(Assessment assessment)
|
||||
{
|
||||
await Navigation.PushAsync(new AssessmentPage(assessment));
|
||||
}
|
||||
|
||||
private async void AddAssessmentButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
if (_oa is not null && _pa is not null)
|
||||
{
|
||||
await DisplayAlert("Info", "Cannot add any more assessments", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
var action = await DisplayActionSheet("Which type of lesson do you want to add?", "Cancel", null, "Performance",
|
||||
"Objective");
|
||||
|
||||
if (action is null or "Cancel") return;
|
||||
|
||||
var assessment = new Assessment
|
||||
{
|
||||
CourseId = _course.Id,
|
||||
StartDate = DateTime.Now,
|
||||
EndDate = DateTime.Today.AddDays(30),
|
||||
StartNotifCheck = false,
|
||||
EndNotifCheck = false
|
||||
};
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case "Objective":
|
||||
if (_oa is not null)
|
||||
{
|
||||
await DisplayAlert("Info", "Cannot add any more objective assessments", "Ok");
|
||||
break;
|
||||
}
|
||||
assessment.Type = AssessmentType.Objective;
|
||||
assessment.Name = "Objective Assessment";
|
||||
break;
|
||||
case "Performance":
|
||||
if (_pa is not null)
|
||||
{
|
||||
await DisplayAlert("Info", "Cannot add any more performance assessments", "Ok");
|
||||
break;
|
||||
}
|
||||
assessment.Type = AssessmentType.Performance;
|
||||
assessment.Name = "Performance Assessment";
|
||||
break;
|
||||
}
|
||||
|
||||
await DatabaseService.AddAssessment(assessment);
|
||||
|
||||
await RefreshAssessmentsList();
|
||||
}
|
||||
}
|
||||
66
WguApp/Views/HomePage.xaml
Normal file
66
WguApp/Views/HomePage.xaml
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="WguApp.Views.HomePage"
|
||||
Title="Home">
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Add"
|
||||
Order="Primary"
|
||||
Priority="0"
|
||||
Clicked="TestButton_OnClicked"
|
||||
IconImageSource="{FontImageSource Glyph='', FontFamily='Phosphor', Size=24, Color=AliceBlue}" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<Grid HorizontalOptions="Fill"
|
||||
Padding="30, 20"
|
||||
RowDefinitions="Auto, Auto, *, Auto">
|
||||
|
||||
<Grid RowDefinitions="*, Auto"
|
||||
ColumnDefinitions="*, Auto"
|
||||
HorizontalOptions="Fill"
|
||||
HeightRequest="40"
|
||||
Grid.Row="0">
|
||||
|
||||
<Label Text="Terms"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontSize="15"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Fill"
|
||||
HorizontalTextAlignment="Start"
|
||||
HeightRequest="20" />
|
||||
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Text=""
|
||||
FontFamily="Phosphor"
|
||||
FontSize="15"
|
||||
WidthRequest="20"
|
||||
HeightRequest="20"
|
||||
TextColor="AliceBlue"
|
||||
BackgroundColor="Transparent"
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="Center"
|
||||
Clicked="AddTermButton_OnClicked"/>
|
||||
</Grid>
|
||||
|
||||
<BoxView
|
||||
Grid.Row="1"
|
||||
Color="AliceBlue"
|
||||
HeightRequest="2"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="0, 0, 0, 20" />
|
||||
|
||||
<ScrollView HorizontalOptions="Fill"
|
||||
HorizontalScrollBarVisibility="Never"
|
||||
Grid.Row="2">
|
||||
<VerticalStackLayout x:Name="TermButtonStack"
|
||||
Margin="0,10"
|
||||
HorizontalOptions="Fill"
|
||||
Spacing="5"/>
|
||||
</ScrollView>
|
||||
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
79
WguApp/Views/HomePage.xaml.cs
Normal file
79
WguApp/Views/HomePage.xaml.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WguApp.Controls;
|
||||
using WguApp.Models;
|
||||
using WguApp.Services;
|
||||
|
||||
namespace WguApp.Views;
|
||||
|
||||
public partial class HomePage : ContentPage
|
||||
{
|
||||
|
||||
private List<Term> _terms = [];
|
||||
|
||||
public HomePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_ = RefreshTermList();
|
||||
}
|
||||
|
||||
private async Task RefreshTermList()
|
||||
{
|
||||
_terms.Clear();
|
||||
_terms = await DatabaseService.GetAllTerms();
|
||||
|
||||
TermButtonStack.Children.Clear();
|
||||
|
||||
|
||||
|
||||
foreach (var term in _terms)
|
||||
{
|
||||
var btn = new CustomButton()
|
||||
{
|
||||
Text = term.Name,
|
||||
DateText = $"{DateOnly.FromDateTime(term.StartDate).ToString()} - {DateOnly.FromDateTime(term.EndDate).ToString()}"
|
||||
};
|
||||
|
||||
TermButtonStack.Add(btn);
|
||||
|
||||
btn.Clicked += (sender, e) =>
|
||||
{
|
||||
HandleTermButtonClick(term);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async void AddTermButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
var newTerm = new Term()
|
||||
{
|
||||
Name = "New Term",
|
||||
StartDate = DateTime.Today,
|
||||
EndDate = DateTime.Today.AddDays(30)
|
||||
};
|
||||
|
||||
await DatabaseService.AddTerm(newTerm);
|
||||
|
||||
await RefreshTermList();
|
||||
}
|
||||
|
||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
||||
{
|
||||
await RefreshTermList();
|
||||
}
|
||||
|
||||
private void HandleTermButtonClick(Term term)
|
||||
{
|
||||
Navigation.PushAsync(new TermPage(term));
|
||||
}
|
||||
|
||||
private void TestButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
Navigation.PushAsync(new TestPage());
|
||||
}
|
||||
}
|
||||
134
WguApp/Views/TermPage.xaml
Normal file
134
WguApp/Views/TermPage.xaml
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="WguApp.Views.TermPage"
|
||||
Title="Term">
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Save"
|
||||
Order="Primary"
|
||||
Priority="0"
|
||||
IconImageSource="{FontImageSource Glyph='', FontFamily='Phosphor', Size=20, Color=AliceBlue}"
|
||||
Clicked="SaveButton_OnClicked"/>
|
||||
<ToolbarItem Text="Delete"
|
||||
Order="Primary"
|
||||
Priority="0"
|
||||
IconImageSource="{FontImageSource Glyph='', FontFamily='Phosphor', Size=20, Color=Red}"
|
||||
Clicked="DeleteButton_OnClicked"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Content>
|
||||
<Grid RowDefinitions="*">
|
||||
<ScrollView HorizontalOptions="Fill"
|
||||
HorizontalScrollBarVisibility="Never">
|
||||
<VerticalStackLayout HorizontalOptions="Fill">
|
||||
<Label Text="Term Info"
|
||||
FontAttributes="Bold"
|
||||
FontSize="20"
|
||||
Margin="20, 10, 20, 5"/>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, *"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Title:"
|
||||
VerticalOptions="Center"
|
||||
FontAttributes="Bold" />
|
||||
|
||||
<Entry x:Name="TitleEntry"
|
||||
Grid.Column="1"
|
||||
Placeholder="Enter value here..."
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, *"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Start date:"
|
||||
VerticalOptions="Center"
|
||||
FontAttributes="Bold" />
|
||||
|
||||
<DatePicker x:Name="StartDatePicker"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="Auto, *"
|
||||
ColumnSpacing="10"
|
||||
Padding="5"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="20, 10">
|
||||
|
||||
<Label Grid.Column="0"
|
||||
Text="Expected end date:"
|
||||
VerticalOptions="Center"
|
||||
FontAttributes="Bold" />
|
||||
|
||||
<DatePicker x:Name="EndDatePicker"
|
||||
Grid.Column="1"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="200"
|
||||
HorizontalOptions="End" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid RowDefinitions="*, Auto"
|
||||
ColumnDefinitions="*, Auto"
|
||||
HorizontalOptions="Fill"
|
||||
HeightRequest="40"
|
||||
Margin="30, 20, 30, 0">
|
||||
|
||||
<Label Text="Courses"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontSize="15"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Fill"
|
||||
HorizontalTextAlignment="Start"
|
||||
HeightRequest="20" />
|
||||
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Text=""
|
||||
FontFamily="Phosphor"
|
||||
FontSize="15"
|
||||
WidthRequest="20"
|
||||
HeightRequest="20"
|
||||
TextColor="AliceBlue"
|
||||
BackgroundColor="Transparent"
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="Center"
|
||||
Clicked="AddCourseButton_OnClicked"/>
|
||||
</Grid>
|
||||
|
||||
<BoxView
|
||||
Color="AliceBlue"
|
||||
HeightRequest="2"
|
||||
HorizontalOptions="Fill"
|
||||
Margin="30, 0, 30, 20" />
|
||||
|
||||
|
||||
|
||||
<VerticalStackLayout x:Name="CourseButtonStack"
|
||||
Margin="30,10"
|
||||
HorizontalOptions="Fill"
|
||||
Spacing="5"/>
|
||||
</VerticalStackLayout>
|
||||
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
147
WguApp/Views/TermPage.xaml.cs
Normal file
147
WguApp/Views/TermPage.xaml.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WguApp.Controls;
|
||||
using WguApp.Models;
|
||||
using WguApp.Services;
|
||||
|
||||
namespace WguApp.Views;
|
||||
|
||||
public partial class TermPage : ContentPage
|
||||
{
|
||||
|
||||
private Term _term;
|
||||
|
||||
private List<Course> _courses = [];
|
||||
|
||||
public TermPage(Term term)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_term = term;
|
||||
|
||||
Title = string.IsNullOrWhiteSpace(_term.Name) ? "Term" : _term.Name;
|
||||
TitleEntry.Text = _term.Name;
|
||||
|
||||
StartDatePicker.Date = _term.StartDate;
|
||||
EndDatePicker.Date = _term.EndDate;
|
||||
}
|
||||
|
||||
private async Task RefreshCourseList()
|
||||
{
|
||||
_courses.Clear();
|
||||
_courses = await DatabaseService.GetCoursesByTermId(_term.Id);
|
||||
|
||||
CourseButtonStack.Children.Clear();
|
||||
|
||||
foreach (var course in _courses)
|
||||
{
|
||||
var btn = new CustomButton()
|
||||
{
|
||||
Text = course.Name,
|
||||
DateText = $"{DateOnly.FromDateTime(course.StartDate).ToString()} - {DateOnly.FromDateTime(course.EndDate).ToString()}"
|
||||
};
|
||||
|
||||
CourseButtonStack.Add(btn);
|
||||
|
||||
btn.Clicked += (sender, e) =>
|
||||
{
|
||||
HandleCourseButtonClick(course);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
await RefreshCourseList();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await DisplayAlert("Error", e.Message, "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
private async void HandleCourseButtonClick(Course course)
|
||||
{
|
||||
await Navigation.PushAsync(new CoursePage(course));
|
||||
}
|
||||
|
||||
private async void SaveButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
var validationResult = ValidateFields();
|
||||
|
||||
if (!validationResult.result)
|
||||
{
|
||||
await DisplayAlert("Validation Error", validationResult.msg, "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
_term.Name = TitleEntry.Text;
|
||||
_term.StartDate = StartDatePicker.Date;
|
||||
_term.EndDate = EndDatePicker.Date;
|
||||
|
||||
var updateResult = await DatabaseService.UpdateTerm(_term);
|
||||
|
||||
if (updateResult)
|
||||
{
|
||||
await DisplayAlert("Info", $"{_term.Name} Saved!", "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
await DisplayAlert("Error", "Could not save term", "Ok");
|
||||
}
|
||||
|
||||
Title = _term.Name;
|
||||
}
|
||||
|
||||
private (string msg, bool result) ValidateFields()
|
||||
{
|
||||
var message = string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(TitleEntry.Text)) message += "Title cannot be blank\n";
|
||||
if (StartDatePicker.Date > EndDatePicker.Date) message += "Start Date cannot be after the End Date\n";
|
||||
|
||||
return string.IsNullOrWhiteSpace(message) ? (message, true) : (message, false);
|
||||
}
|
||||
|
||||
private async void DeleteButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
var result = await DisplayAlert("Delete Term", $"Do you really want to delete '{_term.Name}'? This action cannot be undone.", "Delete", "Cancel");
|
||||
if (!result) return;
|
||||
|
||||
await DatabaseService.DeleteTerm(_term);
|
||||
await Navigation.PopAsync();
|
||||
}
|
||||
|
||||
private async void AddCourseButton_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
if (_courses.Count >= 6)
|
||||
{
|
||||
await DisplayAlert("Info", $"Cannot add more than 6 courses per term", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
var course = new Course()
|
||||
{
|
||||
TermId = _term.Id,
|
||||
Name = "New Course",
|
||||
StartDate = DateTime.Today,
|
||||
EndDate = DateTime.Today.AddDays(30),
|
||||
InstructorName = "",
|
||||
InstructorEmail = "",
|
||||
InstructorPhone = "",
|
||||
StartNotifCheck = false,
|
||||
EndNotifCheck = false,
|
||||
Status = CourseStatus.Planned,
|
||||
Notes = ""
|
||||
};
|
||||
|
||||
await DatabaseService.AddCourse(course);
|
||||
|
||||
await RefreshCourseList();
|
||||
}
|
||||
}
|
||||
39
WguApp/Views/TestPage.xaml
Normal file
39
WguApp/Views/TestPage.xaml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="WguApp.Views.TestPage"
|
||||
Title="Test">
|
||||
<ContentPage.Content>
|
||||
<VerticalStackLayout Spacing="10">
|
||||
<Button
|
||||
Text="Test notification"
|
||||
Clicked="TestBtn_OnClicked"/>
|
||||
|
||||
<Button Text="List scheduled notifications"
|
||||
Clicked="ListNotifs_Clicked"/>
|
||||
|
||||
<Button Text="Clear all notifications"
|
||||
Clicked="ClearAllNotifs_Clicked"/>
|
||||
|
||||
<Button Text="Test Share"
|
||||
Clicked="ShareButton_OnClick"/>
|
||||
|
||||
<Button
|
||||
Text="Add sample data"
|
||||
Clicked="AddData_OnCLicked"></Button>
|
||||
|
||||
<Button Text="Delete data"
|
||||
Clicked="Delete_OnClicked"/>
|
||||
|
||||
<Button Text="Test logger"
|
||||
Clicked="TestLogger_Clicked"/>
|
||||
|
||||
<Button Text="Show log file"
|
||||
Clicked="ShowLog_Clicked"/>
|
||||
|
||||
<Button Text="Clear Log"
|
||||
Clicked="ClearLog_Clicked"/>
|
||||
</VerticalStackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
120
WguApp/Views/TestPage.xaml.cs
Normal file
120
WguApp/Views/TestPage.xaml.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plugin.LocalNotification;
|
||||
using WguApp.Services;
|
||||
|
||||
namespace WguApp.Views;
|
||||
|
||||
public partial class TestPage : ContentPage
|
||||
{
|
||||
public TestPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void TestBtn_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
if (await LocalNotificationCenter.Current.AreNotificationsEnabled() == false)
|
||||
{
|
||||
await LocalNotificationCenter.Current.RequestNotificationPermission();
|
||||
}
|
||||
|
||||
var notification = new NotificationRequest
|
||||
{
|
||||
NotificationId = 1,
|
||||
Title = "Notification Test",
|
||||
Description = "Success!",
|
||||
Schedule =
|
||||
{
|
||||
NotifyTime = DateTime.Now.AddSeconds(30),
|
||||
RepeatType = NotificationRepeat.No
|
||||
}
|
||||
};
|
||||
await LocalNotificationCenter.Current.Show(notification);
|
||||
|
||||
await DisplayAlert("Info", "A test notification should appear in 30 seconds", "ok");
|
||||
}
|
||||
|
||||
private async void AddData_OnCLicked(object? sender, EventArgs e)
|
||||
{
|
||||
var result = await DisplayAlert("Load Sample Data", "Do you really want to load DB sample data? This will delete ALL data from the database. This action cannot be undone.", "Yes", "No");
|
||||
if (!result) return;
|
||||
|
||||
await DatabaseService.LoadSampleData();
|
||||
|
||||
var terms = await DatabaseService.GetAllTerms();
|
||||
var courses = await DatabaseService.GetAllCourses();
|
||||
var assessments = await DatabaseService.GetAllAssessments();
|
||||
|
||||
await DisplayAlert("Info", $"Tried to load sample db data, there are now {terms.Count} Terms, {courses.Count} Courses, and {assessments.Count} Assessments", "Ok");
|
||||
}
|
||||
|
||||
private async void Delete_OnClicked(object? sender, EventArgs e)
|
||||
{
|
||||
var terms = await DatabaseService.GetAllTerms();
|
||||
var courses = await DatabaseService.GetAllCourses();
|
||||
var assessments = await DatabaseService.GetAllAssessments();
|
||||
|
||||
var result = await DisplayAlert("Delete DB Data", $"Do you really want to delete the DB data? This will delete ALL data from the database. This action cannot be undone.\nThere are currently {terms.Count} Terms, {courses.Count} Courses, and {assessments.Count} Assessments", "Yes", "No");
|
||||
if (!result) return;
|
||||
|
||||
await DatabaseService.ClearDbData();
|
||||
|
||||
terms = await DatabaseService.GetAllTerms();
|
||||
courses = await DatabaseService.GetAllCourses();
|
||||
assessments = await DatabaseService.GetAllAssessments();
|
||||
|
||||
await DisplayAlert("Info", $"Tried to delete db data, there are now {terms.Count} Terms, {courses.Count} Courses, and {assessments.Count} Assessments", "Ok");
|
||||
}
|
||||
|
||||
private async void ShareButton_OnClick(object? sender, EventArgs e)
|
||||
{
|
||||
await Share.Default.RequestAsync(new ShareTextRequest
|
||||
{
|
||||
Text = "Test Share Text",
|
||||
Title = "Share Text"
|
||||
});
|
||||
}
|
||||
|
||||
private async void ListNotifs_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
|
||||
|
||||
var message = pendingNotifs.Aggregate($"-- Scheduled notifications ({pendingNotifs.Count}) --\n",
|
||||
(current, notif) => current + $"{notif.Title} : {notif.Schedule.NotifyTime}\n");
|
||||
|
||||
await DisplayAlert("Info", message, "Ok");
|
||||
}
|
||||
|
||||
private void TestLogger_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
LoggerService.LogToFile("Test");
|
||||
}
|
||||
|
||||
private async void ClearAllNotifs_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
var pendingNotifs = await LocalNotificationCenter.Current.GetPendingNotificationList();
|
||||
|
||||
foreach (var notificationRequest in pendingNotifs)
|
||||
{
|
||||
await LocalNotificationService.CancelNotification(notificationRequest.NotificationId);
|
||||
}
|
||||
}
|
||||
|
||||
private async void ShowLog_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
var logFilePath = Path.Combine(FileSystem.AppDataDirectory, "log.txt");
|
||||
|
||||
await DisplayAlert("Log", await File.ReadAllTextAsync(logFilePath), "Ok");
|
||||
}
|
||||
|
||||
private void ClearLog_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
var logFilePath = Path.Combine(FileSystem.AppDataDirectory, "log.txt");
|
||||
|
||||
File.WriteAllText(logFilePath, "");
|
||||
}
|
||||
}
|
||||
70
WguApp/WguApp.csproj
Normal file
70
WguApp/WguApp.csproj
Normal file
@@ -0,0 +1,70 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net9.0-tizen</TargetFrameworks> -->
|
||||
|
||||
<!-- Note for MacCatalyst:
|
||||
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
|
||||
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
|
||||
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
|
||||
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
|
||||
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
|
||||
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>WguApp</RootNamespace>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<!-- Display name -->
|
||||
<ApplicationTitle>WguApp</ApplicationTitle>
|
||||
|
||||
<!-- App Identifier -->
|
||||
<ApplicationId>com.chrisbell.wguapp</ApplicationId>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- App Icon -->
|
||||
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4"/>
|
||||
|
||||
<!-- Splash Screen -->
|
||||
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128"/>
|
||||
|
||||
<!-- Images -->
|
||||
<MauiImage Include="Resources\Images\*"/>
|
||||
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185"/>
|
||||
|
||||
<!-- Custom Fonts -->
|
||||
<MauiFont Include="Resources\Fonts\*"/>
|
||||
|
||||
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
|
||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.8"/>
|
||||
<PackageReference Include="Plugin.LocalNotification" Version="12.0.2" />
|
||||
<PackageReference Include="sqlite-net-pcl" Version="1.10.196-beta" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.11" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
16
WguApp/WguApp.sln
Normal file
16
WguApp/WguApp.sln
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WguApp", "WguApp.csproj", "{BB2F04F1-B5E0-4852-8AAA-AD1AB18D7011}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{BB2F04F1-B5E0-4852-8AAA-AD1AB18D7011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BB2F04F1-B5E0-4852-8AAA-AD1AB18D7011}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BB2F04F1-B5E0-4852-8AAA-AD1AB18D7011}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BB2F04F1-B5E0-4852-8AAA-AD1AB18D7011}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
2
WguApp/WguApp.sln.DotSettings.user
Normal file
2
WguApp/WguApp.sln.DotSettings.user
Normal file
@@ -0,0 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADateOnly_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Fchris_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fb7bf1a4162ee5b47e01ff05d38423e295c7bbb45f3c7b3b77ab51d949e7e741b_003FDateOnly_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||
BIN
commit-history.txt
Normal file
BIN
commit-history.txt
Normal file
Binary file not shown.
BIN
wireframe.png
Normal file
BIN
wireframe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 225 KiB |
1670
wireframe.svg
Normal file
1670
wireframe.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 90 KiB |
Reference in New Issue
Block a user