Add initial project files and configuration for CORP_MAUI application

This commit is contained in:
Данил Ярош 2026-01-12 09:02:03 +03:00
commit bcecc24013
137 changed files with 5067 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/

13
.idea/.idea.CORP-MAUI/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,13 @@
# Игнорируемые файлы по умолчанию
/shelf/
/workspace.xml
# Игнорируемые файлы Rider
/projectSettingsUpdater.xml
/contentModel.xml
/modules.xml
/.idea.CORP-MAUI.iml
# HTTP-клиент на основе редактора
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="RiderAndroidProjectSystem" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AskMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Ask2AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EditMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="CORP-MAUI">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.activity.activity">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.activity.activity/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.activity.activity/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.activity.activity-ktx">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.activity.activity-ktx/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.activity.activity-ktx/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.annotation.annotation">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.annotation/1.9.1.3/jar/androidx.annotation.annotation.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.annotation.annotation-experimental">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.annotation.annotation-experimental/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.annotation.annotation-experimental/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.annotation.annotation-jvm">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.annotation.jvm/1.9.1.3/jar/androidx.annotation.annotation-jvm.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.appcompat.appcompat">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.appcompat.appcompat/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.appcompat.appcompat/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.appcompat.appcompat-resources">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.appcompat.appcompat-resources/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.appcompat.appcompat-resources/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.arch.core.core-common">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.arch.core.common/2.2.0.16/jar/androidx.arch.core.core-common.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.arch.core.core-runtime">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.arch.core.core-runtime/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.arch.core.core-runtime/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.browser.browser">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.browser.browser/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.browser.browser/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.cardview.cardview">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.cardview.cardview/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.cardview.cardview/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.collection.collection">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.collection/1.5.0.1/jar/androidx.collection.collection.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.collection.collection-jvm">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.collection.jvm/1.5.0.1/jar/androidx.collection.collection-jvm.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.collection.collection-ktx">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.collection.ktx/1.5.0.1/jar/androidx.collection.collection-ktx.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.concurrent.concurrent-futures">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.concurrent.futures/1.2.0.6/jar/androidx.concurrent.concurrent-futures.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.constraintlayout.constraintlayout">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.constraintlayout.constraintlayout/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.constraintlayout.constraintlayout/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.constraintlayout.constraintlayout-core">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.constraintlayout.core/1.1.1.1/jar/androidx.constraintlayout.constraintlayout-core.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.coordinatorlayout.coordinatorlayout">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.coordinatorlayout.coordinatorlayout/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.coordinatorlayout.coordinatorlayout/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.core.core">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.core.core/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.core.core/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.core.core-ktx">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.core.core-ktx/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.core.core-ktx/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.core.core-viewtree">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.core.core-viewtree/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.core.core-viewtree/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.cursoradapter.cursoradapter">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.cursoradapter.cursoradapter/classes.jar" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.customview.customview">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.customview.customview/classes.jar" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.customview.customview-poolingcontainer">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.customview.customview-poolingcontainer/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.customview.customview-poolingcontainer/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.drawerlayout.drawerlayout">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.drawerlayout.drawerlayout/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.drawerlayout.drawerlayout/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.dynamicanimation.dynamicanimation">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.dynamicanimation.dynamicanimation/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.dynamicanimation.dynamicanimation/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.emoji2.emoji2">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.emoji2.emoji2/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.emoji2.emoji2/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.emoji2.emoji2-views-helper">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.emoji2.emoji2-views-helper/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.emoji2.emoji2-views-helper/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.exifinterface.exifinterface">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.exifinterface.exifinterface/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.exifinterface.exifinterface/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.fragment.fragment">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.fragment.fragment/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.fragment.fragment/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.fragment.fragment-ktx">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.fragment.fragment-ktx/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.fragment.fragment-ktx/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.interpolator.interpolator">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.interpolator.interpolator/classes.jar" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-common">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.lifecycle.common/2.8.7.3/jar/androidx.lifecycle.lifecycle-common.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-common-jvm">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.lifecycle.common.jvm/2.8.7.3/jar/androidx.lifecycle.lifecycle-common-jvm.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-livedata">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-livedata/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-livedata/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-livedata-core">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-livedata-core/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-livedata-core/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-livedata-core-ktx">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-livedata-core-ktx/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-livedata-core-ktx/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-process">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-process/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-process/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-runtime-android">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-runtime-android/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-runtime-android/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-runtime-ktx-android">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-runtime-ktx-android/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-runtime-ktx-android/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-viewmodel-android">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-viewmodel-android/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-viewmodel-android/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-viewmodel-ktx">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-viewmodel-ktx/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-viewmodel-ktx/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.lifecycle.lifecycle-viewmodel-savedstate">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-viewmodel-savedstate/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.lifecycle.lifecycle-viewmodel-savedstate/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.loader.loader">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.loader.loader/classes.jar" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.navigation.navigation-common">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-common/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-common/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.navigation.navigation-fragment">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-fragment/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-fragment/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.navigation.navigation-runtime">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-runtime/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-runtime/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.navigation.navigation-ui">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-ui/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.navigation.navigation-ui/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.profileinstaller.profileinstaller">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.profileinstaller.profileinstaller/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.profileinstaller.profileinstaller/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.recyclerview.recyclerview">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.recyclerview.recyclerview/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.recyclerview.recyclerview/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="androidx.resourceinspection.resourceinspection-annotation">
<CLASSES>
<root url="jar://$USER_HOME$/.nuget/packages/xamarin.androidx.resourceinspection.annotation/1.0.1.20/jar/androidx.resourceinspection.resourceinspection-annotation.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.savedstate.savedstate">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.savedstate.savedstate/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.savedstate.savedstate/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.savedstate.savedstate-ktx">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.savedstate.savedstate-ktx/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.savedstate.savedstate-ktx/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.security.security-crypto">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.security.security-crypto/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.security.security-crypto/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.slidingpanelayout.slidingpanelayout">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.slidingpanelayout.slidingpanelayout/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.slidingpanelayout.slidingpanelayout/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.startup.startup-runtime">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.startup.startup-runtime/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.startup.startup-runtime/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.swiperefreshlayout.swiperefreshlayout">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.swiperefreshlayout.swiperefreshlayout/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.swiperefreshlayout.swiperefreshlayout/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.tracing.tracing">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.tracing.tracing/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.tracing.tracing/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.transition.transition">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.transition.transition/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.transition.transition/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.vectordrawable.vectordrawable">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.vectordrawable.vectordrawable/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.vectordrawable.vectordrawable/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.vectordrawable.vectordrawable-animated">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.vectordrawable.vectordrawable-animated/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.vectordrawable.vectordrawable-animated/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.versionedparcelable.versionedparcelable">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.versionedparcelable.versionedparcelable/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.versionedparcelable.versionedparcelable/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.viewpager2.viewpager2">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.viewpager2.viewpager2/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.viewpager2.viewpager2/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.viewpager.viewpager">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.viewpager.viewpager/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.viewpager.viewpager/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.window.extensions.core.core">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.window.extensions.core.core/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.window.extensions.core.core/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="androidx.window.window">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.window.window/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/androidx.window.window/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="com.google.android.material.material">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/com.google.android.material.material/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/com.google.android.material.material/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="gifdecoder">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/gifdecoder/classes.jar" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="glide">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/glide/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/glide/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="maui">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/maui/classes.jar" />
<root url="file://$PROJECT_DIR$/../../../../temp/JetBrains/xamarinAarPackages/maui/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

6
.idea/.idea.CORP-MAUI/.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

153
ANDROID_SETUP.md Normal file
View File

@ -0,0 +1,153 @@
# 🤖 Настройка Android SDK для CORP-MAUI
## Проблема
При сборке Android проекта выдается ошибка:
```
error XA5300: Не удалось найти каталог пакета SDK для Android
```
## Решение
У вас установлен Android SDK по пути: `D:\Applications\Android\SDK`
### Способ 1: Использование Directory.Build.props (рекомендуется)
Файл `Directory.Build.props` уже создан в корне решения со следующим содержимым:
```xml
<Project>
<PropertyGroup>
<!-- Путь к Android SDK -->
<AndroidSdkDirectory>D:\Applications\Android\SDK</AndroidSdkDirectory>
</PropertyGroup>
</Project>
```
### Способ 2: Установка переменных окружения
Установите системные переменные окружения:
**Через PowerShell (от имени администратора):**
```powershell
[System.Environment]::SetEnvironmentVariable("ANDROID_HOME", "D:\Applications\Android\SDK", "User")
[System.Environment]::SetEnvironmentVariable("ANDROID_SDK_ROOT", "D:\Applications\Android\SDK", "User")
```
**Через GUI Windows:**
1. Откройте "Система" → "Дополнительные параметры системы"
2. Нажмите "Переменные среды"
3. В разделе "Переменные среды пользователя" нажмите "Создать"
4. Создайте переменные:
- `ANDROID_HOME` = `D:\Applications\Android\SDK`
- `ANDROID_SDK_ROOT` = `D:\Applications\Android\SDK`
5. Нажмите "ОК" и перезапустите IDE
### Способ 3: Использование скриптов сборки
В проекте созданы скрипты для удобной сборки:
**PowerShell скрипт (рекомендуется):**
```powershell
.\build-android.ps1
```
**Batch скрипт:**
```batch
build-android.bat
```
Скрипты автоматически:
- Устанавливают переменные окружения
- Проверяют наличие Android SDK
- Очищают предыдущую сборку
- Восстанавливают зависимости
- Собирают проект для Android
## Проверка установки
После применения любого из способов, проверьте сборку:
```powershell
cd D:\Danil\Projects\DOTNET\CORP-MAUI
dotnet build -c Debug -f net9.0-android
```
Или используйте скрипт:
```powershell
.\build-android.ps1
```
## Требования для Android
Убедитесь, что установлены:
1. **Android SDK Platform** (минимум API 21 для CORP-MAUI)
2. **Android SDK Build-Tools**
3. **Android SDK Platform-Tools**
4. **Android Emulator** (для тестирования)
Проверить установленные компоненты можно в Android Studio:
- Tools → SDK Manager → SDK Platforms
- Tools → SDK Manager → SDK Tools
## Сборка для разных конфигураций
```powershell
# Debug сборка
dotnet build -c Debug -f net9.0-android
# Release сборка
dotnet build -c Release -f net9.0-android
# Запуск на эмуляторе
dotnet build -t:Run -f net9.0-android
```
## Возможные проблемы
### 1. "Java SDK not found"
Установите JDK 17 или выше и добавьте в PATH.
### 2. "Android SDK tools not found"
Убедитесь, что в `D:\Applications\Android\SDK` есть папки:
- `platforms`
- `platform-tools`
- `build-tools`
### 3. Rider не видит Android SDK
1. File → Settings → Build, Execution, Deployment → Toolset and Build
2. Укажите путь к Android SDK: `D:\Applications\Android\SDK`
3. Перезапустите Rider
### 4. После установки переменных среды ничего не изменилось
**Перезапустите:**
- PowerShell / терминал
- JetBrains Rider / Visual Studio
- В крайнем случае - систему
## Вывод APK
После успешной сборки APK файлы находятся в:
```
CORP-MAUI\bin\Debug\net9.0-android\
```
Файлы:
- `com.companyname.corpmaui.apk` - неподписанный APK
- `com.companyname.corpmaui-Signed.apk` - подписанный APK для установки
## Установка APK на устройство
```powershell
# Через ADB
adb install "CORP-MAUI\bin\Debug\net9.0-android\com.companyname.corpmaui-Signed.apk"
# Или используйте Rider
# Run → Edit Configurations → + → .NET MAUI → выберите Android устройство
```
---
**Дата:** 2026-01-09
**Версия:** 1.0

16
CORP-MAUI.sln Normal file
View File

@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CORP-MAUI", "CORP-MAUI\CORP-MAUI.csproj", "{8F7550AD-4C76-4AF1-83C3-E744FE20B02C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8F7550AD-4C76-4AF1-83C3-E744FE20B02C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F7550AD-4C76-4AF1-83C3-E744FE20B02C}.Release|Any CPU.Build.0 = Release|Any CPU
{8F7550AD-4C76-4AF1-83C3-E744FE20B02C}.Debug|Any CPU.ActiveCfg = Android|Any CPU
{8F7550AD-4C76-4AF1-83C3-E744FE20B02C}.Debug|Any CPU.Build.0 = Android|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,6 @@
<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_003AApplication_002Ecs_002Fl_003AC_0021_003FUsers_003F_041D_0430_0442_0430_043B_044C_044F_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ff22149983bac48248d71c7a379de87496f7620_003F5f_003F5808932b_003FApplication_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AApplyPropertiesVisitor_002Ecs_002Fl_003AC_0021_003FUsers_003F_041D_0430_0442_0430_043B_044C_044F_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F3687bba8cb9dcb48ecc525e424af18af03833292dd05261903e25b49fb3a7ae_003FApplyPropertiesVisitor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003AC_0021_003FUsers_003F_041D_0430_0442_0430_043B_044C_044F_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fbd1d5c50194fea68ff3559c160230b0ab50f5acf4ce3061bffd6d62958e2182_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMauiWinUIApplication_002Ecs_002Fl_003AC_0021_003FUsers_003F_041D_0430_0442_0430_043B_044C_044F_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Feb4628845efd624a4bdad5d73b53774c81232eee27ca2aa293d869e5e566_003FMauiWinUIApplication_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APages_005FProfilePage_002Examl_002Esg_002Ecs_002Fl_003AC_0021_003FUsers_003F_041D_0430_0442_0430_043B_044C_044F_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2dc829dd3f62e98b28b779bb99a37aa7f9c521_003FPages_005FProfilePage_002Examl_002Esg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

14
CORP-MAUI/App.xaml Normal file
View 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:CORP_MAUI"
x:Class="CORP_MAUI.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

28
CORP-MAUI/App.xaml.cs Normal file
View File

@ -0,0 +1,28 @@
using CORP_MAUI.Pages;
namespace CORP_MAUI;
public partial class App : Application
{
public App()
{
InitializeComponent();
}
protected override Window CreateWindow(IActivationState? activationState)
{
// Проверяем, есть ли сохраненный токен
var hasToken = SecureStorage.Default.GetAsync("auth_token").Result != null;
if (hasToken)
{
// Пользователь уже вошел в систему
return new Window(new AppShell());
}
else
{
// Показываем страницу входа
return new Window(new NavigationPage(new LoginPage()));
}
}
}

24
CORP-MAUI/AppShell.xaml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="CORP_MAUI.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:CORP_MAUI.Pages"
Title="Корпоративный портал"
FlyoutBackgroundColor="{StaticResource Primary}">
<TabBar>
<ShellContent
Title="Сотрудники"
Icon="dotnet_bot.png"
ContentTemplate="{DataTemplate pages:UsersPage}"
Route="UsersPage" />
<ShellContent
Title="Профиль"
Icon="dotnet_bot.png"
ContentTemplate="{DataTemplate pages:ProfilePage}"
Route="ProfilePage" />
</TabBar>
</Shell>

View File

@ -0,0 +1,44 @@
using CORP_MAUI.Pages;
namespace CORP_MAUI;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
// Регистрация маршрутов для навигации
Routing.RegisterRoute(nameof(ChatPage), typeof(ChatPage));
// Инициализация при загрузке
_ = InitializeAsync();
}
private async Task InitializeAsync()
{
try
{
// Инициализируем сервисы
ServiceProvider.Initialize();
// Проверяем, авторизован ли пользователь (токены загружаются автоматически в ApiService)
if (ServiceProvider.ApiService.IsAuthenticated)
{
// Получаем токен для WebSocket
var accessToken = await SecureStorage.GetAsync("api.jwt_access");
if (!string.IsNullOrEmpty(accessToken))
{
// Подключаем WebSocket
await ServiceProvider.WebSocketService.ConnectAsync(accessToken);
}
}
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", $"Ошибка инициализации: {ex.Message}", "OK");
}
}
}

View File

@ -0,0 +1,72 @@
<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>CORP_MAUI</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Display name -->
<ApplicationTitle>CORP-MAUI</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.corpmaui</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>
<Configurations>Debug;Release;Android</Configurations>
<Platforms>AnyCPU</Platforms>
</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.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="System.Net.WebSockets.Client" Version="4.3.2" />
</ItemGroup>
</Project>

36
CORP-MAUI/MainPage.xaml Normal file
View File

@ -0,0 +1,36 @@
<?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="CORP_MAUI.MainPage">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot in a hovercraft number nine" />
<Label
Text="Hello, World!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label
Text="Welcome to &#10;.NET Multi-platform App UI"
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I" />
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>

View File

@ -0,0 +1,23 @@
namespace CORP_MAUI;
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
}
private void OnCounterClicked(object? sender, EventArgs e)
{
count++;
if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
SemanticScreenReader.Announce(CounterBtn.Text);
}
}

24
CORP-MAUI/MauiProgram.cs Normal file
View File

@ -0,0 +1,24 @@
using Microsoft.Extensions.Logging;
namespace CORP_MAUI;
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");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}

View File

@ -0,0 +1,10 @@
namespace CORP_MAUI.Models;
public class AuthResponse
{
public bool Success { get; set; }
public string Token { get; set; } = string.Empty;
public User? User { get; set; }
public string Message { get; set; } = string.Empty;
}

View File

@ -0,0 +1,22 @@
namespace CORP_MAUI.Models;
public class Message
{
public int Id { get; set; }
public int SenderId { get; set; }
public string SenderName { get; set; } = string.Empty;
public int? ReceiverId { get; set; }
public string ReceiverName { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public DateTime Timestamp { get; set; }
public bool IsRead { get; set; }
public MessageType Type { get; set; }
}
public enum MessageType
{
Personal,
Group,
System
}

14
CORP-MAUI/Models/User.cs Normal file
View File

@ -0,0 +1,14 @@
namespace CORP_MAUI.Models;
public class User
{
public int Id { get; set; }
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string FullName { get; set; } = string.Empty;
public string Department { get; set; } = string.Empty;
public string Position { get; set; } = string.Empty;
public string AvatarUrl { get; set; } = string.Empty;
public bool IsOnline { get; set; }
}

View File

@ -0,0 +1,173 @@
<?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"
xmlns:local="clr-namespace:CORP_MAUI.Pages"
x:Class="CORP_MAUI.Pages.ChatPage"
Title="Чат">
<Grid RowDefinitions="Auto,*,Auto">
<!-- Шапка с информацией о собеседнике -->
<Border
Grid.Row="0"
Padding="15"
BackgroundColor="{StaticResource Primary}"
Shadow="{Shadow Brush=Black, Opacity=0.3, Offset='0,2', Radius=4}">
<HorizontalStackLayout Spacing="10">
<!-- Аватар -->
<Border
WidthRequest="50"
HeightRequest="50"
StrokeShape="RoundRectangle 25"
Padding="0"
BackgroundColor="White">
<Image
x:Name="RecipientAvatar"
Source="dotnet_bot.png"
Aspect="AspectFill"/>
</Border>
<VerticalStackLayout VerticalOptions="Center">
<Label
x:Name="RecipientName"
Text="Выберите собеседника"
FontSize="18"
FontAttributes="Bold"
TextColor="White"/>
<Label
x:Name="RecipientStatus"
Text="Offline"
FontSize="12"
TextColor="White"
Opacity="0.8"/>
</VerticalStackLayout>
</HorizontalStackLayout>
</Border>
<!-- Список сообщений -->
<CollectionView
Grid.Row="1"
x:Name="MessagesCollectionView"
SelectionMode="None"
Margin="10">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type local:MessageViewModel}">
<Grid Padding="5">
<!-- Сообщение отправленное -->
<Border
HorizontalOptions="End"
MaximumWidthRequest="300"
BackgroundColor="{StaticResource Primary}"
StrokeShape="RoundRectangle 15"
Padding="10"
Margin="50,0,0,0"
Shadow="{Shadow Brush=Black, Opacity=0.2, Offset='0,1', Radius=3}">
<Border.Triggers>
<DataTrigger TargetType="Border" Binding="{Binding IsMyMessage}" Value="False">
<Setter Property="HorizontalOptions" Value="Start"/>
<Setter Property="BackgroundColor" Value="{StaticResource Gray200}"/>
<Setter Property="Margin" Value="0,0,50,0"/>
</DataTrigger>
</Border.Triggers>
<VerticalStackLayout Spacing="5">
<Label
Text="{Binding SenderName}"
FontSize="12"
FontAttributes="Bold"
TextColor="White">
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding IsMyMessage}" Value="False">
<Setter Property="TextColor" Value="{StaticResource Gray900}"/>
</DataTrigger>
</Label.Triggers>
</Label>
<Label
Text="{Binding Content}"
FontSize="14"
TextColor="White">
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding IsMyMessage}" Value="False">
<Setter Property="TextColor" Value="{StaticResource Gray900}"/>
</DataTrigger>
</Label.Triggers>
</Label>
<Label
Text="{Binding Timestamp, StringFormat='{0:HH:mm}'}"
FontSize="10"
HorizontalOptions="End"
TextColor="White"
Opacity="0.7">
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding IsMyMessage}" Value="False">
<Setter Property="TextColor" Value="{StaticResource Gray600}"/>
</DataTrigger>
</Label.Triggers>
</Label>
</VerticalStackLayout>
</Border>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<!-- Панель ввода сообщения -->
<Border
Grid.Row="2"
Padding="10"
BackgroundColor="{StaticResource Gray100}"
Shadow="{Shadow Brush=Black, Opacity=0.3, Offset='0,-2', Radius=4}">
<Grid ColumnDefinitions="*,Auto">
<Entry
x:Name="MessageEntry"
Grid.Column="0"
Placeholder="Введите сообщение..."
PlaceholderColor="{StaticResource Gray400}"
TextColor="{StaticResource Gray900}"
BackgroundColor="White"
HeightRequest="45"
VerticalOptions="Center"
TextChanged="OnMessageTextChanged"
Completed="OnSendMessageClicked"/>
<Button
Grid.Column="1"
x:Name="SendButton"
Text="➤"
FontSize="24"
WidthRequest="50"
HeightRequest="45"
BackgroundColor="{StaticResource Primary}"
TextColor="White"
CornerRadius="10"
Margin="10,0,0,0"
Clicked="OnSendMessageClicked"/>
</Grid>
</Border>
<!-- Индикатор подключения -->
<Border
Grid.Row="1"
x:Name="ConnectionIndicator"
IsVisible="False"
BackgroundColor="{StaticResource Secondary}"
Padding="10"
StrokeShape="RoundRectangle 20"
VerticalOptions="Start"
HorizontalOptions="Center"
Margin="0,10,0,0"
Shadow="{Shadow Brush=Black, Opacity=0.3, Offset='0,2', Radius=4}">
<Label
Text="Подключение..."
TextColor="White"
FontSize="12"/>
</Border>
</Grid>
</ContentPage>

View File

@ -0,0 +1,213 @@
using System.Collections.ObjectModel;
using CORP_MAUI.Models;
using CORP_MAUI.Services;
namespace CORP_MAUI.Pages;
public partial class ChatPage : ContentPage
{
private readonly ObservableCollection<MessageViewModel> _messages;
private User _currentUser = new();
private User _recipient;
private System.Timers.Timer _typingTimer = new();
public ChatPage(User recipient)
{
InitializeComponent();
_recipient = recipient;
_messages = new ObservableCollection<MessageViewModel>();
MessagesCollectionView.ItemsSource = _messages;
// Подписываемся на события WebSocket
ServiceProvider.WebSocketService.MessageReceived += OnMessageReceived;
ServiceProvider.WebSocketService.ConnectionStatusChanged += OnConnectionStatusChanged;
// Инициализация
_ = InitializeAsync();
}
private async Task InitializeAsync()
{
try
{
// Получаем текущего пользователя
var user = await ServiceProvider.ApiService.GetCurrentUserAsync();
if (user != null)
{
_currentUser = user;
}
// Отображаем информацию о получателе
RecipientName.Text = _recipient.FullName ?? _recipient.Username;
RecipientStatus.Text = _recipient.IsOnline ? "В сети" : "Не в сети";
// Загружаем историю сообщений
await LoadMessagesAsync();
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", $"Не удалось загрузить данные: {ex.Message}", "OK");
}
}
private async Task LoadMessagesAsync()
{
try
{
var messages = await ServiceProvider.ApiService.GetMessagesAsync(_recipient.Id);
_messages.Clear();
foreach (var message in messages.OrderBy(m => m.Timestamp))
{
_messages.Add(new MessageViewModel
{
Id = message.Id,
SenderId = message.SenderId,
SenderName = message.SenderName,
Content = message.Content,
Timestamp = message.Timestamp,
IsMyMessage = message.SenderId == _currentUser?.Id
});
}
// Прокручиваем к последнему сообщению
if (_messages.Any())
{
MessagesCollectionView.ScrollTo(_messages.Last(), position: ScrollToPosition.End, animate: false);
}
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", $"Не удалось загрузить сообщения: {ex.Message}", "OK");
}
}
private async void OnSendMessageClicked(object sender, EventArgs e)
{
var content = MessageEntry.Text?.Trim();
if (string.IsNullOrEmpty(content))
return;
try
{
var message = new Message
{
SenderId = _currentUser.Id,
SenderName = _currentUser.FullName ?? _currentUser.Username,
ReceiverId = _recipient.Id,
ReceiverName = _recipient.FullName ?? _recipient.Username,
Content = content,
Timestamp = DateTime.Now,
Type = MessageType.Personal
};
// Отправляем через WebSocket
if (ServiceProvider.WebSocketService.IsConnected)
{
await ServiceProvider.WebSocketService.SendMessageAsync(message);
}
else
{
// Резервный вариант через REST API
await ServiceProvider.ApiService.SendMessageAsync(message);
}
// Добавляем сообщение в список
_messages.Add(new MessageViewModel
{
SenderId = message.SenderId,
SenderName = message.SenderName,
Content = message.Content,
Timestamp = message.Timestamp,
IsMyMessage = true
});
// Очищаем поле ввода
MessageEntry.Text = string.Empty;
// Прокручиваем к последнему сообщению
MessagesCollectionView.ScrollTo(_messages.Last(), position: ScrollToPosition.End, animate: true);
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", $"Не удалось отправить сообщение: {ex.Message}", "OK");
}
}
private void OnMessageTextChanged(object sender, TextChangedEventArgs e)
{
// Отправляем индикатор набора текста
if (!string.IsNullOrEmpty(e.NewTextValue) && ServiceProvider.WebSocketService.IsConnected)
{
_ = ServiceProvider.WebSocketService.SendTypingIndicatorAsync(_recipient.Id, true);
// Отменяем предыдущий таймер
_typingTimer?.Stop();
_typingTimer?.Dispose();
// Создаем новый таймер для отправки статуса "не печатает"
_typingTimer = new System.Timers.Timer(2000);
_typingTimer.Elapsed += async (s, args) =>
{
await ServiceProvider.WebSocketService.SendTypingIndicatorAsync(_recipient.Id, false);
_typingTimer?.Dispose();
};
_typingTimer.Start();
}
}
private void OnMessageReceived(object? sender, Message message)
{
// Проверяем, что сообщение от нашего собеседника
if (message.SenderId == _recipient.Id)
{
MainThread.BeginInvokeOnMainThread(() =>
{
_messages.Add(new MessageViewModel
{
Id = message.Id,
SenderId = message.SenderId,
SenderName = message.SenderName,
Content = message.Content,
Timestamp = message.Timestamp,
IsMyMessage = false
});
MessagesCollectionView.ScrollTo(_messages.Last(), position: ScrollToPosition.End, animate: true);
});
}
}
private void OnConnectionStatusChanged(object? sender, bool isConnected)
{
MainThread.BeginInvokeOnMainThread(() =>
{
ConnectionIndicator.IsVisible = !isConnected;
});
}
protected override void OnDisappearing()
{
base.OnDisappearing();
// Отписываемся от событий
ServiceProvider.WebSocketService.MessageReceived -= OnMessageReceived;
ServiceProvider.WebSocketService.ConnectionStatusChanged -= OnConnectionStatusChanged;
_typingTimer?.Dispose();
}
}
public class MessageViewModel
{
public int Id { get; set; }
public int SenderId { get; set; }
public string SenderName { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public DateTime Timestamp { get; set; }
public bool IsMyMessage { get; set; }
}

View File

@ -0,0 +1,122 @@
<?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="CORP_MAUI.Pages.LoginPage"
Title="Вход в систему"
BackgroundColor="{StaticResource Primary}">
<ScrollView>
<VerticalStackLayout
Padding="30"
Spacing="20"
VerticalOptions="Center">
<!-- Логотип -->
<Image
Source="dotnet_bot.png"
HeightRequest="120"
WidthRequest="120"
HorizontalOptions="Center"
Margin="0,0,0,30"/>
<!-- Заголовок -->
<Label
Text="Корпоративный портал"
FontSize="28"
FontAttributes="Bold"
HorizontalOptions="Center"
TextColor="White"/>
<Label
Text="Войдите для продолжения"
FontSize="16"
HorizontalOptions="Center"
TextColor="White"
Opacity="0.8"
Margin="0,0,0,20"/>
<!-- Форма входа -->
<Frame
Padding="20"
CornerRadius="15"
BackgroundColor="White"
HasShadow="True">
<VerticalStackLayout Spacing="15">
<!-- Имя пользователя -->
<Label
Text="Имя пользователя"
FontSize="14"
TextColor="{StaticResource Gray900}"/>
<Entry
x:Name="UsernameEntry"
Placeholder="Введите имя пользователя"
PlaceholderColor="{StaticResource Gray400}"
TextColor="{StaticResource Gray900}"
BackgroundColor="{StaticResource Gray100}"
HeightRequest="50"/>
<!-- Пароль -->
<Label
Text="Пароль"
FontSize="14"
TextColor="{StaticResource Gray900}"
Margin="0,10,0,0"/>
<Entry
x:Name="PasswordEntry"
Placeholder="Введите пароль"
IsPassword="True"
PlaceholderColor="{StaticResource Gray400}"
TextColor="{StaticResource Gray900}"
BackgroundColor="{StaticResource Gray100}"
HeightRequest="50"/>
<!-- Сообщение об ошибке -->
<Label
x:Name="ErrorLabel"
IsVisible="False"
TextColor="Red"
FontSize="12"
HorizontalOptions="Center"/>
<!-- Кнопка входа -->
<Button
x:Name="LoginButton"
Text="Войти"
BackgroundColor="{StaticResource Primary}"
TextColor="White"
FontSize="16"
FontAttributes="Bold"
HeightRequest="50"
CornerRadius="10"
Margin="0,20,0,0"
Clicked="OnLoginClicked"/>
<!-- Индикатор загрузки -->
<ActivityIndicator
x:Name="LoadingIndicator"
IsRunning="False"
IsVisible="False"
Color="{StaticResource Primary}"
HorizontalOptions="Center"/>
</VerticalStackLayout>
</Frame>
<!-- Дополнительная информация -->
<Label
Text="Версия 1.0.0"
FontSize="12"
HorizontalOptions="Center"
TextColor="White"
Opacity="0.6"
Margin="0,30,0,0"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>

View File

@ -0,0 +1,132 @@
using System.Diagnostics;
namespace CORP_MAUI.Pages;
public partial class LoginPage : ContentPage
{
public LoginPage()
{
InitializeComponent();
Debug.WriteLine("[LoginPage] Страница входа инициализирована");
}
private async void OnLoginClicked(object sender, EventArgs e)
{
var username = UsernameEntry.Text?.Trim();
var password = PasswordEntry.Text?.Trim();
Debug.WriteLine($"\n[LoginPage] >>> Кнопка входа нажата");
Debug.WriteLine($"[LoginPage] Username: {username}");
// Валидация
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
Debug.WriteLine($"[LoginPage] ❌ Валидация не прошла - пустые поля");
await ShowError("Пожалуйста, заполните все поля");
return;
}
// Показываем индикатор загрузки
SetLoadingState(true);
try
{
Debug.WriteLine($"[LoginPage] >>> Вызываем ApiService.LoginAsync...\n");
// Выполняем вход
var result = await ServiceProvider.ApiService.LoginAsync(username, password);
Debug.WriteLine($"\n[LoginPage] <<< Получен результат логина");
Debug.WriteLine($"[LoginPage] Success: {result.Success}");
Debug.WriteLine($"[LoginPage] Message: {result.Message}");
if (result.Success)
{
Debug.WriteLine($"[LoginPage] ✅ Логин успешен! Переходим к WebSocket...");
// Подключаемся к WebSocket
try
{
// Получаем токен (из результата или напрямую из ApiService)
var token = result.Token ?? ServiceProvider.ApiService.GetAccessToken();
if (string.IsNullOrEmpty(token))
{
Debug.WriteLine($"[LoginPage] ❌ Токен отсутствует!");
await DisplayAlert("Ошибка", "Не удалось получить токен авторизации", "OK");
return;
}
Debug.WriteLine($"[LoginPage] >>> Подключение к WebSocket...");
Debug.WriteLine($"[LoginPage] >>> Token (first 30 chars): {token.Substring(0, Math.Min(30, token.Length))}...");
Debug.WriteLine($"[LoginPage] >>> Token length: {token.Length}");
await ServiceProvider.WebSocketService.ConnectAsync(token);
Debug.WriteLine($"[LoginPage] ✅ WebSocket подключен!");
}
catch (Exception wsEx)
{
Debug.WriteLine($"[LoginPage] ❌ WebSocket ошибка: {wsEx.GetType().Name}");
Debug.WriteLine($"[LoginPage] Message: {wsEx.Message}");
Debug.WriteLine($"[LoginPage] StackTrace:\n{wsEx.StackTrace}");
// Показываем предупреждение, но продолжаем работу
await DisplayAlert("Предупреждение",
$"Не удалось подключиться к WebSocket.\nРеал-тайм сообщения будут недоступны.\n\nОшибка: {wsEx.Message}",
"OK");
}
// Сохраняем данные пользователя (токены уже сохранены в ApiService)
if (result.User != null)
{
await SecureStorage.SetAsync("user_id", result.User.Id.ToString());
await SecureStorage.SetAsync("username", result.User.Username);
}
Debug.WriteLine($"[LoginPage] >>> Переход на главную страницу");
// Переходим на главную страницу
if (Application.Current?.Windows.Count > 0)
{
Application.Current.Windows[0].Page = new AppShell();
}
}
else
{
Debug.WriteLine($"[LoginPage] ❌ Логин неуспешен");
await ShowError(result.Message ?? "Ошибка входа. Проверьте учетные данные.");
}
}
catch (Exception ex)
{
Debug.WriteLine($"[LoginPage] ❌ Exception: {ex.GetType().Name}");
Debug.WriteLine($"[LoginPage] Message: {ex.Message}");
Debug.WriteLine($"[LoginPage] StackTrace: {ex.StackTrace}");
await ShowError($"Ошибка подключения: {ex.Message}");
}
finally
{
SetLoadingState(false);
}
}
private async Task ShowError(string message)
{
ErrorLabel.Text = message;
ErrorLabel.IsVisible = true;
// Скрываем сообщение через 5 секунд
await Task.Delay(5000);
ErrorLabel.IsVisible = false;
}
private void SetLoadingState(bool isLoading)
{
LoginButton.IsEnabled = !isLoading;
LoadingIndicator.IsRunning = isLoading;
LoadingIndicator.IsVisible = isLoading;
UsernameEntry.IsEnabled = !isLoading;
PasswordEntry.IsEnabled = !isLoading;
}
}

View 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="CORP_MAUI.Pages.ProfilePage"
Title="Профиль">
<ScrollView>
<VerticalStackLayout Padding="20" Spacing="20">
<!-- Аватар и имя -->
<Frame
Padding="20"
CornerRadius="15"
BackgroundColor="White"
HasShadow="True">
<VerticalStackLayout Spacing="15">
<Frame
WidthRequest="100"
HeightRequest="100"
CornerRadius="50"
Padding="0"
IsClippedToBounds="True"
HasShadow="False"
BackgroundColor="{StaticResource Gray200}"
HorizontalOptions="Center">
<Image
x:Name="AvatarImage"
Source="dotnet_bot.png"
Aspect="AspectFill"/>
</Frame>
<Label
x:Name="FullNameLabel"
Text="Загрузка..."
FontSize="24"
FontAttributes="Bold"
HorizontalOptions="Center"
TextColor="{StaticResource Gray900}"/>
<Label
x:Name="UsernameLabel"
Text="@username"
FontSize="16"
HorizontalOptions="Center"
TextColor="{StaticResource Gray600}"/>
</VerticalStackLayout>
</Frame>
<!-- Информация о пользователе -->
<Frame
Padding="20"
CornerRadius="15"
BackgroundColor="White"
HasShadow="True">
<VerticalStackLayout Spacing="15">
<Label
Text="Информация"
FontSize="18"
FontAttributes="Bold"
TextColor="{StaticResource Gray900}"/>
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto,Auto" RowSpacing="10">
<Label Grid.Row="0" Grid.Column="0" Text="Email:" FontAttributes="Bold" TextColor="{StaticResource Gray700}"/>
<Label Grid.Row="0" Grid.Column="1" x:Name="EmailLabel" Text="-" TextColor="{StaticResource Gray600}" Margin="10,0,0,0"/>
<Label Grid.Row="1" Grid.Column="0" Text="Должность:" FontAttributes="Bold" TextColor="{StaticResource Gray700}"/>
<Label Grid.Row="1" Grid.Column="1" x:Name="PositionLabel" Text="-" TextColor="{StaticResource Gray600}" Margin="10,0,0,0"/>
<Label Grid.Row="2" Grid.Column="0" Text="Отдел:" FontAttributes="Bold" TextColor="{StaticResource Gray700}"/>
<Label Grid.Row="2" Grid.Column="1" x:Name="DepartmentLabel" Text="-" TextColor="{StaticResource Gray600}" Margin="10,0,0,0"/>
<Label Grid.Row="3" Grid.Column="0" Text="Статус:" FontAttributes="Bold" TextColor="{StaticResource Gray700}"/>
<Label Grid.Row="3" Grid.Column="1" x:Name="StatusLabel" Text="В сети" TextColor="LimeGreen" Margin="10,0,0,0"/>
</Grid>
</VerticalStackLayout>
</Frame>
<!-- Действия -->
<Frame
Padding="20"
CornerRadius="15"
BackgroundColor="White"
HasShadow="True">
<VerticalStackLayout Spacing="10">
<Label
Text="Настройки"
FontSize="18"
FontAttributes="Bold"
TextColor="{StaticResource Gray900}"
Margin="0,0,0,10"/>
<Button
Text="Обновить профиль"
BackgroundColor="{StaticResource Primary}"
TextColor="White"
CornerRadius="10"
HeightRequest="45"
Clicked="OnRefreshClicked"/>
<Button
Text="Выйти из системы"
BackgroundColor="{StaticResource Secondary}"
TextColor="White"
CornerRadius="10"
HeightRequest="45"
Clicked="OnLogoutClicked"/>
</VerticalStackLayout>
</Frame>
<!-- Индикатор загрузки -->
<ActivityIndicator
x:Name="LoadingIndicator"
IsRunning="False"
IsVisible="False"
Color="{StaticResource Primary}"
HorizontalOptions="Center"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>

View File

@ -0,0 +1,92 @@
using CORP_MAUI.Models;
namespace CORP_MAUI.Pages;
public partial class ProfilePage : ContentPage
{
private User _currentUser = new();
public ProfilePage()
{
InitializeComponent();
_ = LoadProfileAsync();
}
private async Task LoadProfileAsync()
{
try
{
LoadingIndicator.IsVisible = true;
LoadingIndicator.IsRunning = true;
// Загружаем профиль
var user = await ServiceProvider.ApiService.GetCurrentUserAsync();
if (user != null)
{
_currentUser = user;
FullNameLabel.Text = _currentUser.FullName ?? "Не указано";
UsernameLabel.Text = $"@{_currentUser.Username}";
EmailLabel.Text = _currentUser.Email ?? "Не указано";
PositionLabel.Text = _currentUser.Position ?? "Не указано";
DepartmentLabel.Text = _currentUser.Department ?? "Не указано";
StatusLabel.Text = _currentUser.IsOnline ? "В сети" : "Не в сети";
StatusLabel.TextColor = _currentUser.IsOnline ? Colors.LimeGreen : Colors.Gray;
if (!string.IsNullOrEmpty(_currentUser.AvatarUrl))
{
AvatarImage.Source = _currentUser.AvatarUrl;
}
}
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", $"Не удалось загрузить профиль: {ex.Message}", "OK");
}
finally
{
LoadingIndicator.IsVisible = false;
LoadingIndicator.IsRunning = false;
}
}
private async void OnRefreshClicked(object sender, EventArgs e)
{
await LoadProfileAsync();
}
private async void OnLogoutClicked(object sender, EventArgs e)
{
var result = await DisplayAlert("Выход", "Вы уверены, что хотите выйти?", "Да", "Нет");
if (result)
{
try
{
// Обновляем статус пользователя
await ServiceProvider.ApiService.UpdateStatusAsync(false);
// Отключаем WebSocket
await ServiceProvider.WebSocketService.DisconnectAsync();
// Выходим из системы (очищаем токены)
ServiceProvider.ApiService.Logout();
// Очищаем сохраненные данные
SecureStorage.Remove("user_id");
SecureStorage.Remove("username");
// Переходим на страницу входа
if (Application.Current?.Windows.Count > 0)
{
Application.Current.Windows[0].Page = new NavigationPage(new LoginPage());
}
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", $"Ошибка при выходе: {ex.Message}", "OK");
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More