diff --git a/.github/workflows/eeos-android-ci.yml b/.github/workflows/eeos-android-ci.yml
new file mode 100644
index 00000000..b58b6472
--- /dev/null
+++ b/.github/workflows/eeos-android-ci.yml
@@ -0,0 +1,26 @@
+name: Android CI
+
+on:
+ push:
+ paths:
+ - "AOS/**"
+ branches: [ "main" ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ cache: gradle
+
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+ - name: Build with Gradle
+ run: ./gradlew build
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..757f2edf
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
\ No newline at end of file
diff --git a/.idea/black-company.iml b/.idea/black-company.iml
new file mode 100644
index 00000000..d6ebd480
--- /dev/null
+++ b/.idea/black-company.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..f79668c3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..35eb1ddf
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/.gitignore b/AOS/.gitignore
new file mode 100644
index 00000000..aa724b77
--- /dev/null
+++ b/AOS/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/AOS/.idea/.name b/AOS/.idea/.name
new file mode 100644
index 00000000..42e1e53e
--- /dev/null
+++ b/AOS/.idea/.name
@@ -0,0 +1 @@
+eeos
\ No newline at end of file
diff --git a/AOS/.idea/compiler.xml b/AOS/.idea/compiler.xml
new file mode 100644
index 00000000..b589d56e
--- /dev/null
+++ b/AOS/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/.idea/gradle.xml b/AOS/.idea/gradle.xml
new file mode 100644
index 00000000..a2d7c213
--- /dev/null
+++ b/AOS/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/.idea/inspectionProfiles/Project_Default.xml b/AOS/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..44ca2d9b
--- /dev/null
+++ b/AOS/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/.idea/kotlinc.xml b/AOS/.idea/kotlinc.xml
new file mode 100644
index 00000000..e1eea1d6
--- /dev/null
+++ b/AOS/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/.idea/misc.xml b/AOS/.idea/misc.xml
new file mode 100644
index 00000000..773fe0fb
--- /dev/null
+++ b/AOS/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/.idea/shelf/Changes.xml b/AOS/.idea/shelf/Changes.xml
new file mode 100644
index 00000000..6e1971e6
--- /dev/null
+++ b/AOS/.idea/shelf/Changes.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/AOS/.idea/shelf/Changes/shelved.patch b/AOS/.idea/shelf/Changes/shelved.patch
new file mode 100644
index 00000000..0370fd21
--- /dev/null
+++ b/AOS/.idea/shelf/Changes/shelved.patch
@@ -0,0 +1,143 @@
+Index: app/src/main/java/com/example/eeos/ui/theme/Color.kt
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
+<+>package com.example.eeos.ui.theme\n\nimport androidx.compose.ui.graphics.Color\n\nval Purple80 = Color(0xFFD0BCFF)\nval PurpleGrey80 = Color(0xFFCCC2DC)\nval Pink80 = Color(0xFFEFB8C8)\n\nval Purple40 = Color(0xFF6650a4)\nval PurpleGrey40 = Color(0xFF625b71)\nval Pink40 = Color(0xFF7D5260)
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/app/src/main/java/com/example/eeos/ui/theme/Color.kt b/app/src/main/java/com/example/eeos/ui/theme/Color.kt
+--- a/app/src/main/java/com/example/eeos/ui/theme/Color.kt (revision b728e6928e505c38a75a3659743b0bf4168b4458)
++++ b/app/src/main/java/com/example/eeos/ui/theme/Color.kt (date 1698893823018)
+@@ -8,4 +8,4 @@
+
+ val Purple40 = Color(0xFF6650a4)
+ val PurpleGrey40 = Color(0xFF625b71)
+-val Pink40 = Color(0xFF7D5260)
+\ No newline at end of file
++val Pink40 = Color(0xFF7D5260)
+Index: app/src/main/java/com/example/eeos/MainActivity.kt
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
+<+>package com.example.eeos\n\nimport android.os.Bundle\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.setContent\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.tooling.preview.Preview\nimport com.example.eeos.ui.theme.EeosTheme\n\nclass MainActivity : ComponentActivity() {\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n setContent {\n EeosTheme {\n // A surface container using the 'background' color from the theme\n Surface(\n modifier = Modifier.fillMaxSize(),\n color = MaterialTheme.colorScheme.background\n ) {\n Greeting(\"Android\")\n }\n }\n }\n }\n}\n@Composable\nfun Greeting(name: String, modifier: Modifier = Modifier) {\n Text(\n text = \"Hello $name!\",\n modifier = modifier\n )\n}\n@Preview(showBackground = true)\n@Composable\nfun GreetingPreview() {\n EeosTheme {\n Greeting(\"Android\")\n }\n}
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/app/src/main/java/com/example/eeos/MainActivity.kt b/app/src/main/java/com/example/eeos/MainActivity.kt
+--- a/app/src/main/java/com/example/eeos/MainActivity.kt (revision b728e6928e505c38a75a3659743b0bf4168b4458)
++++ b/app/src/main/java/com/example/eeos/MainActivity.kt (date 1698893822999)
+@@ -28,6 +28,7 @@
+ }
+ }
+ }
++
+ @Composable
+ fun Greeting(name: String, modifier: Modifier = Modifier) {
+ Text(
+@@ -35,10 +36,11 @@
+ modifier = modifier
+ )
+ }
++
+ @Preview(showBackground = true)
+ @Composable
+ fun GreetingPreview() {
+ EeosTheme {
+ Greeting("Android")
+ }
+-}
+\ No newline at end of file
++}
+Index: app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
+<+>package com.example.eeos\n\nimport androidx.test.platform.app.InstrumentationRegistry\nimport androidx.test.ext.junit.runners.AndroidJUnit4\n\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\nimport org.junit.Assert.*\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\n@RunWith(AndroidJUnit4::class)\nclass ExampleInstrumentedTest {\n @Test\n fun useAppContext() {\n // Context of the app under test.\n val appContext = InstrumentationRegistry.getInstrumentation().targetContext\n assertEquals(\"com.example.eeos\", appContext.packageName)\n }\n}
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt
+--- a/app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt (revision b728e6928e505c38a75a3659743b0bf4168b4458)
++++ b/app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt (date 1698893822982)
+@@ -1,13 +1,11 @@
+ package com.example.eeos
+
+-import androidx.test.platform.app.InstrumentationRegistry
+ import androidx.test.ext.junit.runners.AndroidJUnit4
+-
++import androidx.test.platform.app.InstrumentationRegistry
++import org.junit.Assert.*
+ import org.junit.Test
+ import org.junit.runner.RunWith
+
+-import org.junit.Assert.*
+-
+ /**
+ * Instrumented test, which will execute on an Android device.
+ *
+@@ -21,4 +19,4 @@
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.eeos", appContext.packageName)
+ }
+-}
+\ No newline at end of file
++}
+Index: app/src/test/java/com/example/eeos/ExampleUnitTest.kt
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
+<+>package com.example.eeos\n\nimport org.junit.Test\n\nimport org.junit.Assert.*\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\nclass ExampleUnitTest {\n @Test\n fun addition_isCorrect() {\n assertEquals(4, 2 + 2)\n }\n}
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/app/src/test/java/com/example/eeos/ExampleUnitTest.kt b/app/src/test/java/com/example/eeos/ExampleUnitTest.kt
+--- a/app/src/test/java/com/example/eeos/ExampleUnitTest.kt (revision b728e6928e505c38a75a3659743b0bf4168b4458)
++++ b/app/src/test/java/com/example/eeos/ExampleUnitTest.kt (date 1698893822912)
+@@ -1,8 +1,7 @@
+ package com.example.eeos
+
+-import org.junit.Test
+-
+ import org.junit.Assert.*
++import org.junit.Test
+
+ /**
+ * Example local unit test, which will execute on the development machine (host).
+@@ -14,4 +13,4 @@
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+-}
+\ No newline at end of file
++}
+Index: app/src/main/java/com/example/eeos/ui/theme/Theme.kt
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
+<+>package com.example.eeos.ui.theme\n\nimport android.app.Activity\nimport android.os.Build\nimport androidx.compose.foundation.isSystemInDarkTheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.darkColorScheme\nimport androidx.compose.material3.dynamicDarkColorScheme\nimport androidx.compose.material3.dynamicLightColorScheme\nimport androidx.compose.material3.lightColorScheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.ui.graphics.toArgb\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalView\nimport androidx.core.view.WindowCompat\n\nprivate val DarkColorScheme = darkColorScheme(\n primary = Purple80,\n secondary = PurpleGrey80,\n tertiary = Pink80\n)\n\nprivate val LightColorScheme = lightColorScheme(\n primary = Purple40,\n secondary = PurpleGrey40,\n tertiary = Pink40\n\n /* Other default colors to override\n background = Color(0xFFFFFBFE),\n surface = Color(0xFFFFFBFE),\n onPrimary = Color.White,\n onSecondary = Color.White,\n onTertiary = Color.White,\n onBackground = Color(0xFF1C1B1F),\n onSurface = Color(0xFF1C1B1F),\n */\n)\n\n@Composable\nfun EeosTheme(\n darkTheme: Boolean = isSystemInDarkTheme(),\n // Dynamic color is available on Android 12+\n dynamicColor: Boolean = true,\n content: @Composable () -> Unit\n) {\n val colorScheme = when {\n dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {\n val context = LocalContext.current\n if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)\n }\n\n darkTheme -> DarkColorScheme\n else -> LightColorScheme\n }\n val view = LocalView.current\n if (!view.isInEditMode) {\n SideEffect {\n val window = (view.context as Activity).window\n window.statusBarColor = colorScheme.primary.toArgb()\n WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme\n }\n }\n\n MaterialTheme(\n colorScheme = colorScheme,\n typography = Typography,\n content = content\n )\n}
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/app/src/main/java/com/example/eeos/ui/theme/Theme.kt b/app/src/main/java/com/example/eeos/ui/theme/Theme.kt
+--- a/app/src/main/java/com/example/eeos/ui/theme/Theme.kt (revision b728e6928e505c38a75a3659743b0bf4168b4458)
++++ b/app/src/main/java/com/example/eeos/ui/theme/Theme.kt (date 1698893823050)
+@@ -67,4 +67,4 @@
+ typography = Typography,
+ content = content
+ )
+-}
+\ No newline at end of file
++}
+Index: app/src/main/java/com/example/eeos/ui/theme/Type.kt
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
+<+>package com.example.eeos.ui.theme\n\nimport androidx.compose.material3.Typography\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.sp\n\n// Set of Material typography styles to start with\nval Typography = Typography(\n bodyLarge = TextStyle(\n fontFamily = FontFamily.Default,\n fontWeight = FontWeight.Normal,\n fontSize = 16.sp,\n lineHeight = 24.sp,\n letterSpacing = 0.5.sp\n )\n /* Other default text styles to override\n titleLarge = TextStyle(\n fontFamily = FontFamily.Default,\n fontWeight = FontWeight.Normal,\n fontSize = 22.sp,\n lineHeight = 28.sp,\n letterSpacing = 0.sp\n ),\n labelSmall = TextStyle(\n fontFamily = FontFamily.Default,\n fontWeight = FontWeight.Medium,\n fontSize = 11.sp,\n lineHeight = 16.sp,\n letterSpacing = 0.5.sp\n )\n */\n)
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/app/src/main/java/com/example/eeos/ui/theme/Type.kt b/app/src/main/java/com/example/eeos/ui/theme/Type.kt
+--- a/app/src/main/java/com/example/eeos/ui/theme/Type.kt (revision b728e6928e505c38a75a3659743b0bf4168b4458)
++++ b/app/src/main/java/com/example/eeos/ui/theme/Type.kt (date 1698893823061)
+@@ -31,4 +31,4 @@
+ letterSpacing = 0.5.sp
+ )
+ */
+-)
+\ No newline at end of file
++)
diff --git a/AOS/.idea/vcs.xml b/AOS/.idea/vcs.xml
new file mode 100644
index 00000000..6c0b8635
--- /dev/null
+++ b/AOS/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/.gitignore b/AOS/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/AOS/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/AOS/app/build.gradle b/AOS/app/build.gradle
new file mode 100644
index 00000000..7a1abc8f
--- /dev/null
+++ b/AOS/app/build.gradle
@@ -0,0 +1,80 @@
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+ id "org.jlleitschuh.gradle.ktlint" version '11.6.1'
+}
+
+android {
+ namespace 'com.example.eeos'
+ compileSdk 33
+
+ defaultConfig {
+ applicationId "com.example.eeos"
+ minSdk 31
+ targetSdk 33
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ buildFeatures {
+ compose true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion '1.3.2'
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+ktlint {
+ android = true
+ ignoreFailures = false
+ disabledRules = ["no-wildcard-imports", "indent"]
+ reporters {
+ reporter "plain"
+ reporter "checkstyle"
+ reporter "sarif"
+ }
+}
+
+dependencies {
+ def nav_version = "2.6.0"
+
+ implementation 'androidx.core:core-ktx:1.8.0'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
+ implementation 'androidx.activity:activity-compose:1.5.1'
+ implementation platform('androidx.compose:compose-bom:2023.06.01')
+ implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
+ implementation 'androidx.compose.ui:ui'
+ implementation 'androidx.compose.ui:ui-graphics'
+ implementation 'androidx.compose.ui:ui-tooling-preview'
+ implementation 'androidx.compose.material3:material3'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.5'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+ androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
+ debugImplementation 'androidx.compose.ui:ui-tooling'
+ debugImplementation 'androidx.compose.ui:ui-test-manifest'
+ implementation "androidx.navigation:navigation-compose:$nav_version"
+}
\ No newline at end of file
diff --git a/AOS/app/proguard-rules.pro b/AOS/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/AOS/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/AOS/app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt b/AOS/app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt
new file mode 100644
index 00000000..4b7772f4
--- /dev/null
+++ b/AOS/app/src/androidTest/java/com/example/eeos/ExampleInstrumentedTest.kt
@@ -0,0 +1,22 @@
+package com.example.eeos
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.*
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.eeos", appContext.packageName)
+ }
+}
diff --git a/AOS/app/src/main/AndroidManifest.xml b/AOS/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..e1798b87
--- /dev/null
+++ b/AOS/app/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/main/eeos_launcher-playstore.png b/AOS/app/src/main/eeos_launcher-playstore.png
new file mode 100644
index 00000000..8e61aaa9
Binary files /dev/null and b/AOS/app/src/main/eeos_launcher-playstore.png differ
diff --git a/AOS/app/src/main/java/com/example/eeos/MainActivity.kt b/AOS/app/src/main/java/com/example/eeos/MainActivity.kt
new file mode 100644
index 00000000..b3b7b431
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/MainActivity.kt
@@ -0,0 +1,32 @@
+package com.example.eeos
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.navigation.EEOSNavGraph
+import com.example.eeos.ui.home.ProgramLists
+import com.example.eeos.ui.theme.EeosTheme
+
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ EeosTheme {
+ EEOSNavGraph()
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun GreetingPreview() {
+ EeosTheme {
+ ProgramLists(
+ programLists = listOf(),
+ onProgramClick = {}
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/navigation/EEOSNavGraph.kt b/AOS/app/src/main/java/com/example/eeos/navigation/EEOSNavGraph.kt
new file mode 100644
index 00000000..a2617ddb
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/navigation/EEOSNavGraph.kt
@@ -0,0 +1,56 @@
+package com.example.eeos.navigation
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.navigation.NavHostController
+import androidx.navigation.NavType
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
+import androidx.navigation.navArgument
+import com.example.eeos.ui.detail.DetailScreen
+import com.example.eeos.ui.home.HomeScreen
+import com.example.eeos.ui.login.LoginScreen
+
+@Composable
+fun EEOSNavGraph(
+ navController: NavHostController = rememberNavController(),
+ startDestination: String = EEOSDestinations.LOGIN_ROUTE,
+ navActions: EEOSNavigationActions = remember(navController) {
+ EEOSNavigationActions(navController)
+ }
+) {
+// val currentNavBackStackEntry by navController.currentBackStackEntryAsState()
+// val currentRoute = currentNavBackStackEntry?.destination?.route ?: startDestination
+
+ NavHost(
+ navController = navController,
+ startDestination = startDestination
+ ) {
+ composable(
+ EEOSDestinations.LOGIN_ROUTE
+ ) {
+ LoginScreen(
+ onClick = { navActions.navigateToHome() }
+ )
+ }
+ composable(
+ EEOSDestinations.HOME_ROUTE
+ ) {
+ HomeScreen(
+ onProgramClick = { navActions.navigateToProgramDetail(1) }
+ )
+ }
+
+ composable(
+ EEOSDestinations.DETAIL_ROUTE,
+ arguments = listOf(
+ navArgument(EEOSDestinationsArgs.PROGRAM_ID_ARG) {
+ type = NavType.IntType; defaultValue = 0
+ }
+ )
+ ) {
+ DetailScreen()
+ }
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/navigation/EEOSNavigation.kt b/AOS/app/src/main/java/com/example/eeos/navigation/EEOSNavigation.kt
new file mode 100644
index 00000000..c7956b47
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/navigation/EEOSNavigation.kt
@@ -0,0 +1,68 @@
+package com.example.eeos.navigation
+
+import androidx.navigation.NavGraph.Companion.findStartDestination
+import androidx.navigation.NavHostController
+
+/**
+ * Screens used in [EEOSDestinations]
+ */
+private object EEOSScreens {
+ const val LOGIN_SCREEN = "login"
+ const val HOME_SCREEN = "home"
+ const val PROGRAM_DETAIL_SCREEN = "programDetail"
+}
+
+/**
+ * Arguments used in [EEOSDestinations] routes
+ */
+object EEOSDestinationsArgs {
+ const val PROGRAM_ID_ARG = "programId"
+}
+
+/**
+ * Destinations used in the [EEOSActivity]
+ */
+object EEOSDestinations {
+ const val LOGIN_ROUTE = EEOSScreens.LOGIN_SCREEN
+ const val HOME_ROUTE = EEOSScreens.HOME_SCREEN
+ const val DETAIL_ROUTE =
+ "${EEOSScreens.PROGRAM_DETAIL_SCREEN}?${EEOSDestinationsArgs.PROGRAM_ID_ARG}={${EEOSDestinationsArgs.PROGRAM_ID_ARG}}" // programDetail/${programId}
+}
+
+/**
+ * Models the navigation actions in the app.
+ */
+class EEOSNavigationActions(private val navController: NavHostController) {
+ fun navigateToLogin() {
+ navController.navigate(EEOSDestinations.LOGIN_ROUTE) {
+ // 로그아웃 시도 후 로그인 페이지로 돌아오며
+ // 모든 BackStack 제거
+ popUpTo(navController.graph.findStartDestination().id)
+ launchSingleTop = true
+ }
+ }
+
+ fun navigateToHome() {
+ navController.navigate(EEOSDestinations.HOME_ROUTE) {
+ // 로그인 후 로그인 화면 BackStack에서 제거
+ // 현재 홈 화면의 State 유지
+ popUpTo(navController.graph.findStartDestination().id) {
+ inclusive = true
+ saveState = true
+ }
+ // Avoid multiple copies of the same destination
+ launchSingleTop = true
+ // 유지된 홈 화면의 상태를 가져옴
+ restoreState = true
+ }
+ }
+
+ fun navigateToProgramDetail(programId: Int = 1) {
+ navController.navigate(
+ "${EEOSScreens.PROGRAM_DETAIL_SCREEN}?${EEOSDestinationsArgs.PROGRAM_ID_ARG}=$programId"
+ ) {
+ popUpTo(EEOSDestinations.HOME_ROUTE)
+ launchSingleTop = true
+ }
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/common/EeosTopAppBar.kt b/AOS/app/src/main/java/com/example/eeos/ui/common/EeosTopAppBar.kt
new file mode 100644
index 00000000..48925f53
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/common/EeosTopAppBar.kt
@@ -0,0 +1,70 @@
+package com.example.eeos.ui.common
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.TopAppBar
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun EeosTopAppBar() {
+ val memberStatus: List = listOf(
+ stringResource(R.string.home_dialog_member_status_am),
+ stringResource(R.string.home_dialog_member_status_rm),
+ stringResource(R.string.home_dialog_member_status_cm),
+ stringResource(R.string.home_dialog_member_status_ob),
+ )
+
+ val memberStatusDialogState = remember {
+ mutableStateOf(false)
+ }
+
+ if (memberStatusDialogState.value) {
+ MemberStatusDialog(
+ onStatusBtnClick = {},
+ onDismissRequest = { memberStatusDialogState.value = false }
+ )
+ }
+
+ TopAppBar(
+ title = {
+ Image(
+ painter = painterResource(id = R.drawable.eeos_logo_monogram),
+ contentDescription = ""
+ )
+ },
+ actions = {
+ MemberInfo(
+ memberStatus = "memberStatus",
+ generation = 24,
+ name = "name",
+ onClick = { memberStatusDialogState.value = true }
+ )
+ Spacer(modifier = Modifier.width(dimensionResource(id = R.dimen.margin_common_screen)))
+ },
+ colors = TopAppBarDefaults.topAppBarColors(
+ containerColor = colorResource(id = R.color.background)
+ )
+ )
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun TopAppBarPreview() {
+ MaterialTheme {
+ EeosTopAppBar()
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/common/MemberInfo.kt b/AOS/app/src/main/java/com/example/eeos/ui/common/MemberInfo.kt
new file mode 100644
index 00000000..f02f14e6
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/common/MemberInfo.kt
@@ -0,0 +1,86 @@
+package com.example.eeos.ui.common
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun MemberInfo(
+ memberStatus: String,
+ generation: Int,
+ name: String,
+ onClick: () -> Unit
+) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Image(
+ painter = painterResource(id = R.drawable.common_mypage_button),
+ contentDescription = "회원 상태 수정",
+ modifier = Modifier.clickable { onClick() }
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_common_screen_member_info_space_between_icon_and_text
+ )
+ )
+ )
+
+ Column(
+ horizontalAlignment = Alignment.End
+ ) {
+ Text(
+ text = memberStatus,
+ style = MaterialTheme.typography.labelSmall,
+ color = colorResource(id = R.color.paragraph)
+ )
+
+ Row {
+ Text(
+ text = generation.toString() + "기",
+ style = MaterialTheme.typography.labelSmall,
+ color = colorResource(id = R.color.paragraph)
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_common_screen_member_info_space_between_texts
+ )
+ )
+ )
+ Text(
+ text = name,
+ style = MaterialTheme.typography.labelSmall,
+ color = colorResource(id = R.color.paragraph)
+ )
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun MemberInfoPreview() {
+ MaterialTheme {
+ MemberInfo(
+ memberStatus = "AM",
+ generation = 24,
+ name = "인텔리",
+ onClick = {}
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/common/MemberStatusButtons.kt b/AOS/app/src/main/java/com/example/eeos/ui/common/MemberStatusButtons.kt
new file mode 100644
index 00000000..57b4b761
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/common/MemberStatusButtons.kt
@@ -0,0 +1,139 @@
+package com.example.eeos.ui.common
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.example.eeos.R
+
+private val memberStatusList = listOf("AM", "RM", "CM", "OB")
+
+@Composable
+fun MemberStatusButtons(
+ memberStatus: String,
+ onClick: () -> Unit
+) {
+ Column {
+ Row {
+ MemberStatusButton(
+ buttonText = memberStatusList[0],
+ isSelected = memberStatusList[0] == memberStatus,
+ onClick = onClick
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_button_horizontal_space
+ )
+ )
+ )
+ MemberStatusButton(
+ buttonText = memberStatusList[1],
+ isSelected = memberStatusList[1] == memberStatus,
+ onClick = onClick
+ )
+ }
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_member_status_dialog_button_vertical_space)
+ )
+ )
+ Row {
+ MemberStatusButton(
+ buttonText = memberStatusList[2],
+ isSelected = memberStatusList[2] == memberStatus,
+ onClick = onClick
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_button_horizontal_space
+ )
+ )
+ )
+ MemberStatusButton(
+ buttonText = memberStatusList[3],
+ isSelected = memberStatusList[3] == memberStatus,
+ onClick = onClick
+ )
+ }
+ }
+}
+
+@Composable
+private fun MemberStatusButton(
+ buttonText: String,
+ isSelected: Boolean,
+ onClick: () -> Unit
+) {
+ val containerColor = if (isSelected) {
+ colorResource(R.color.secondary)
+ } else {
+ colorResource(R.color.gray_100)
+ }
+ val contentColor = if (isSelected) {
+ colorResource(R.color.tertiary_strong)
+ } else {
+ colorResource(R.color.gray_500)
+ }
+
+ Button(
+ onClick = onClick,
+ modifier = Modifier
+ .size(
+ width = dimensionResource(id = R.dimen.size_member_status_dialog_button_width),
+ height = dimensionResource(id = R.dimen.size_member_status_dialog_button_height)
+ ),
+ shape = RoundedCornerShape(7.87.dp),
+ colors = ButtonDefaults.buttonColors(
+ containerColor = containerColor,
+ contentColor = contentColor
+ ),
+ border = BorderStroke(
+ width = dimensionResource(id = R.dimen.size_member_status_dialog_button_stroke),
+ color = contentColor
+ )
+ ) {
+ Text(
+ text = buttonText,
+ style = MaterialTheme.typography.titleLarge
+ )
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun MemberStatusButtonsPreview() {
+ MaterialTheme {
+ MemberStatusButtons(
+ memberStatus = "AM",
+ onClick = {}
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun MemberStatusButtonPreview() {
+ MaterialTheme {
+ MemberStatusButton(
+ buttonText = "AM",
+ isSelected = false,
+ onClick = {}
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/common/MemberStatusDialog.kt b/AOS/app/src/main/java/com/example/eeos/ui/common/MemberStatusDialog.kt
new file mode 100644
index 00000000..e6b7054b
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/common/MemberStatusDialog.kt
@@ -0,0 +1,144 @@
+package com.example.eeos.ui.common
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Card
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.window.Dialog
+import com.example.eeos.R
+
+@Composable
+fun MemberStatusDialog(
+ onStatusBtnClick: () -> Unit,
+ onDismissRequest: () -> Unit
+) {
+ Dialog(onDismissRequest = onDismissRequest) {
+ Card(
+ modifier = Modifier
+ .size(
+ width = dimensionResource(
+ id = R.dimen.size_member_status_dialog_background_width
+ ),
+ height = dimensionResource(
+ id = R.dimen.size_member_status_dialog_background_height
+ )
+ ),
+ shape = RoundedCornerShape(dimensionResource(id = R.dimen.size_corner_20dp)),
+ colors = CardDefaults.cardColors(
+ containerColor = colorResource(R.color.background),
+ contentColor = colorResource(R.color.paragraph)
+ )
+ ) {
+ Row {
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(id = R.dimen.margin_member_status_dialog_background_side)
+ )
+ )
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_background_top
+ )
+ )
+ )
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_space_between_text_and_background
+ )
+ )
+ )
+ Text(
+ text = "/* ToDo */",
+ style = MaterialTheme.typography.bodyLarge
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_space_between_text_and_logout_btn
+ )
+ )
+ )
+ Icon(
+ painter = painterResource(
+ R.drawable.memberstatusdialog_logoutbutton_24dp
+ ),
+ contentDescription = stringResource(
+ id = R.string.home_dialog_logout_button
+ ),
+ modifier = Modifier.clickable {
+ /* ToDo */
+ }
+ )
+ }
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_space_between_texts
+ )
+ )
+ )
+ Text(
+ text = stringResource(id = R.string.home_dialog_description),
+ style = MaterialTheme.typography.bodySmall
+ )
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_space_between_text_and_status_button
+ )
+ )
+ )
+ MemberStatusButtons("AM", onStatusBtnClick)
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(
+ id = R.dimen.margin_member_status_dialog_background_bottom
+ )
+ )
+ )
+ }
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(id = R.dimen.margin_member_status_dialog_background_side)
+ )
+ )
+ }
+ }
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun MemberStatusDialogPreview() {
+ MaterialTheme {
+ MemberStatusDialog(
+ onStatusBtnClick = {},
+ onDismissRequest = {}
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusButton.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusButton.kt
new file mode 100644
index 00000000..a305c4b9
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusButton.kt
@@ -0,0 +1,84 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun AttendStatusButton(
+ buttonText: String,
+ contentColor: Color,
+ containerColor: Color,
+ backgroundColor: Color,
+ isSelected: Boolean,
+ onClick: () -> Unit,
+) {
+ val contentColor = if (isSelected) {
+ contentColor
+ } else {
+ colorResource(R.color.gray_500)
+ }
+ val containerColor = if (isSelected) {
+ containerColor
+ } else {
+ backgroundColor
+ }
+ val strokeColor = if (isSelected) {
+ contentColor
+ } else {
+ colorResource(R.color.transparent)
+ }
+
+ Button(
+ modifier = Modifier
+ .clip(RoundedCornerShape(dimensionResource(id = R.dimen.size_corner_20dp))),
+ onClick = onClick,
+ colors = ButtonDefaults.buttonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = containerColor,
+ disabledContentColor = contentColor
+ ),
+ border = BorderStroke(
+ width = dimensionResource(id = R.dimen.width_stroke_1_2dp),
+ color = strokeColor
+ ),
+ contentPadding = PaddingValues(
+ horizontal = dimensionResource(id = R.dimen.padding_values_35dp),
+ vertical = dimensionResource(id = R.dimen.padding_values_15dp)
+ ),
+ ) {
+ Text(
+ text = buttonText,
+ style = MaterialTheme.typography.bodyLarge,
+ color = contentColor
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun AttendStatusButtonPreview() {
+ MaterialTheme {
+ AttendStatusButton(
+ buttonText = "수요조사에 참여해주세요.",
+ contentColor = colorResource(R.color.success_strong),
+ containerColor = colorResource(R.color.success_light),
+ backgroundColor = colorResource(R.color.gray_100),
+ isSelected = true,
+ onClick = {},
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusButtons.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusButtons.kt
new file mode 100644
index 00000000..c139473c
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusButtons.kt
@@ -0,0 +1,71 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun AttendStatusButtons() {
+ Row(
+ modifier = Modifier.background(
+ color = colorResource(R.color.gray_100),
+ shape = RoundedCornerShape(dimensionResource(id = R.dimen.size_corner_20dp)),
+ )
+ ) {
+ AttendButton() {}
+ LateComeButton() {}
+ AbsentButton() {}
+ }
+}
+
+@Composable
+private fun AttendButton(onClick: () -> Unit) {
+ AttendStatusButton(
+ buttonText = stringResource(R.string.detail_attendees),
+ contentColor = colorResource(R.color.success_strong),
+ containerColor = colorResource(R.color.success_light),
+ backgroundColor = colorResource(R.color.gray_100),
+ isSelected = true,
+ onClick = onClick
+ )
+}
+
+@Composable
+private fun LateComeButton(onClick: () -> Unit) {
+ AttendStatusButton(
+ buttonText = stringResource(R.string.detail_latecomers),
+ contentColor = colorResource(R.color.warning_strong),
+ containerColor = colorResource(R.color.warning_light),
+ backgroundColor = colorResource(R.color.gray_100),
+ isSelected = false,
+ onClick = onClick
+ )
+}
+
+@Composable
+private fun AbsentButton(onClick: () -> Unit) {
+ AttendStatusButton(
+ buttonText = stringResource(R.string.detail_absentees),
+ contentColor = colorResource(R.color.action),
+ containerColor = colorResource(R.color.action_light),
+ backgroundColor = colorResource(R.color.gray_100),
+ isSelected = false,
+ onClick = onClick
+ )
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun AttendStatusButtonsPreview() {
+ MaterialTheme {
+ AttendStatusButtons()
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusChip.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusChip.kt
new file mode 100644
index 00000000..20b7411a
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusChip.kt
@@ -0,0 +1,75 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.DpSize
+import com.example.eeos.R
+
+@Composable
+fun AttendStatusChip(
+ buttonText: String,
+ contentColor: Color,
+ containerColor: Color,
+ isContentLong: Boolean
+) {
+ val dpSize = if (isContentLong) {
+ DpSize(
+ width = dimensionResource(id = R.dimen.width_detail_bottom_sheet_long_button),
+ height = dimensionResource(id = R.dimen.height_detail_bottom_sheet_long_button)
+ )
+ } else {
+ DpSize(
+ width = dimensionResource(id = R.dimen.width_detail_bottom_sheet_short_button),
+ height = dimensionResource(id = R.dimen.height_detail_bottom_sheet_short_button)
+ )
+ }
+
+ Button(
+ modifier = Modifier
+ .size(dpSize)
+ .clip(RoundedCornerShape(dimensionResource(id = R.dimen.size_corner_20dp))),
+ colors = ButtonDefaults.buttonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = containerColor,
+ disabledContentColor = contentColor
+ ),
+ border = BorderStroke(
+ width = dimensionResource(id = R.dimen.width_stroke_1_2dp),
+ color = contentColor
+ ),
+ enabled = false,
+ onClick = {}
+ ) {
+ Text(
+ text = buttonText,
+ style = MaterialTheme.typography.bodyLarge,
+ color = contentColor
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun AttendStatusChipPreview() {
+ MaterialTheme {
+ AttendStatusChip(
+ buttonText = "수요조사 해주세요!",
+ contentColor = colorResource(R.color.success_strong),
+ containerColor = colorResource(R.color.success_light),
+ isContentLong = true
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusChips.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusChips.kt
new file mode 100644
index 00000000..d0b309b4
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusChips.kt
@@ -0,0 +1,76 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun AttendChip() {
+ AttendStatusChip(
+ buttonText = stringResource(R.string.detail_attendees),
+ contentColor = colorResource(R.color.success_strong),
+ containerColor = colorResource(R.color.success_light),
+ isContentLong = false
+ )
+}
+
+@Composable
+fun LateComerChip() {
+ AttendStatusChip(
+ buttonText = stringResource(R.string.detail_latecomers),
+ contentColor = colorResource(R.color.warning_strong),
+ containerColor = colorResource(R.color.warning_light),
+ isContentLong = false
+ )
+}
+
+@Composable
+fun AbsentChip() {
+ AttendStatusChip(
+ buttonText = stringResource(R.string.detail_absentees),
+ contentColor = colorResource(R.color.action),
+ containerColor = colorResource(R.color.action_light),
+ isContentLong = false
+ )
+}
+
+@Composable
+fun RequestSurveyChip() {
+ AttendStatusChip(
+ buttonText = stringResource(R.string.detail_bottom_sheet_do_survey),
+ contentColor = colorResource(R.color.tertiary_strong),
+ containerColor = colorResource(R.color.tertiary),
+ isContentLong = true
+ )
+}
+
+@Composable
+fun RequestAttendCheckChip() {
+ AttendStatusChip(
+ buttonText = stringResource(R.string.detail_bottom_sheet_check_attendance),
+ contentColor = colorResource(R.color.tertiary_strong),
+ containerColor = colorResource(R.color.secondary),
+ isContentLong = true
+ )
+}
+
+@Composable
+fun NonRelatedChip() {
+ AttendStatusChip(
+ buttonText = stringResource(R.string.detail_bottom_sheet_irrelevant),
+ contentColor = colorResource(R.color.stroke_400),
+ containerColor = colorResource(R.color.gray_100),
+ isContentLong = true
+ )
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun NonRelatedChipPreview() {
+ MaterialTheme {
+ RequestAttendCheckChip()
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusInfo.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusInfo.kt
new file mode 100644
index 00000000..ca30839a
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/AttendStatusInfo.kt
@@ -0,0 +1,56 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun AttendStatusInfo(
+ memberInfo: MemberData,
+ attendStatusChip: @Composable () -> Unit
+) {
+ val infoText = "${memberInfo.generation}기 ${memberInfo.name} 님"
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ text = infoText,
+ style = MaterialTheme.typography.titleSmall,
+ color = colorResource(R.color.paragraph)
+ )
+ Spacer(
+ modifier = Modifier.width(
+ width = dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_info_and_chip
+ )
+ )
+ )
+ attendStatusChip()
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun AttendStatusInfoPreview() {
+ MaterialTheme {
+ AttendStatusInfo(
+ memberInfo = MemberData(
+ generation = 24,
+ name = "장현지",
+ attendStatus = AttendStatus.NO_RESPONSE
+ )
+ ) {
+ AttendChip()
+ }
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/BottomSheetContent.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/BottomSheetContent.kt
new file mode 100644
index 00000000..1778fc2f
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/BottomSheetContent.kt
@@ -0,0 +1,96 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun SheetDragHandle() {
+ Column {
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_detail_screen_space_bar_top)
+ )
+ )
+ Image(
+ painterResource(id = R.drawable.detail_bottom_sheet_drag_handle),
+ stringResource(R.string.detail_bottom_sheet_drag_handle_description)
+ )
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_detail_screen_space_bar_bottom)
+ )
+ )
+ }
+}
+
+@Composable
+fun BottomSheetContents() {
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ AttendStatusInfo(
+ memberInfo = MemberData(
+ generation = 24,
+ name = "장현지",
+ attendStatus = AttendStatus.NO_RESPONSE
+ )
+ ) { RequestAttendCheckChip() }
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_info_and_chip
+ )
+ )
+ )
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_detail_screen_space_description_vertical
+ )
+ )
+ )
+ Text(
+ text = stringResource(R.string.detail_bottom_sheet_description),
+ style = MaterialTheme.typography.bodySmall,
+ color = colorResource(R.color.paragraph)
+ )
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_detail_screen_space_description_vertical
+ )
+ )
+ )
+ AttendStatusButtons()
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_detail_screen_space_attend_status_buttons_vertical
+ )
+ )
+ )
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun BottomSheetContentsPreview() {
+ MaterialTheme {
+ BottomSheetContents()
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/DetailScreen.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/DetailScreen.kt
new file mode 100644
index 00000000..6b8103c0
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/DetailScreen.kt
@@ -0,0 +1,96 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.BottomSheetScaffold
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+import com.example.eeos.ui.common.EeosTopAppBar
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun DetailScreen() {
+ BottomSheetScaffold(
+ sheetContent = { BottomSheetContents() },
+ topBar = {
+ EeosTopAppBar()
+ },
+ sheetPeekHeight = dimensionResource(id = R.dimen.height_detail_screen_sheet_peek_height),
+ sheetShape = RoundedCornerShape(
+ topStart = dimensionResource(id = R.dimen.size_corner_25dp),
+ topEnd = dimensionResource(id = R.dimen.size_corner_25dp)
+ ),
+ sheetContainerColor = colorResource(id = R.color.background),
+ sheetContentColor = colorResource(id = R.color.paragraph),
+ sheetShadowElevation = dimensionResource(
+ id = R.dimen.height_detail_screen_sheet_sheet_shadow_elevation
+ ),
+ sheetDragHandle = {
+ SheetDragHandle()
+ },
+ containerColor = colorResource(id = R.color.background)
+ ) {
+ DetailScreenContent()
+ }
+}
+
+@Composable
+private fun DetailScreenContent() {
+ val state = rememberScrollState()
+ Row(
+ modifier = Modifier
+ .fillMaxSize(),
+ horizontalArrangement = Arrangement.Center
+ ) {
+ Spacer(
+ modifier = Modifier.width(
+ width = dimensionResource(id = R.dimen.margin_common_screen)
+ )
+ )
+ Column(
+ modifier = Modifier.verticalScroll(state)
+ ) {
+ ProgramDetail()
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_content_and_attendance
+ )
+ )
+ )
+ MemberLists()
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(R.dimen.height_detail_screen_space_bottom)
+ )
+ )
+ }
+ Spacer(
+ modifier = Modifier.width(
+ width = dimensionResource(id = R.dimen.margin_common_screen)
+ )
+ )
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun DetailScreenPreview() {
+ MaterialTheme {
+ DetailScreen()
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/MemberData.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/MemberData.kt
new file mode 100644
index 00000000..0a99d4d6
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/MemberData.kt
@@ -0,0 +1,11 @@
+package com.example.eeos.ui.detail
+
+data class MemberData(
+ val generation: Int,
+ val name: String,
+ val attendStatus: AttendStatus
+)
+
+enum class AttendStatus {
+ ATTEND, ABSENT, PERCEIVE, NO_RESPONSE, NON_RELATED
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/MemberList.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/MemberList.kt
new file mode 100644
index 00000000..b52085d6
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/MemberList.kt
@@ -0,0 +1,181 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Divider
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+import com.example.eeos.ui.util.NonLazyGrid
+
+data class Attendance(
+ val attendance: String,
+ val painter: Painter,
+ val memberList: List
+)
+
+val sampleMemberList: List = listOf(
+ MemberData(24, "인텔리", attendStatus = AttendStatus.ATTEND),
+ MemberData(22, "만두쓰", attendStatus = AttendStatus.ATTEND),
+ MemberData(25, "지유쓰", attendStatus = AttendStatus.ATTEND),
+ MemberData(25, "스티브", attendStatus = AttendStatus.ATTEND),
+ MemberData(25, "오션쓰", attendStatus = AttendStatus.ATTEND),
+ MemberData(24, "인텔리", attendStatus = AttendStatus.ATTEND),
+ MemberData(22, "만두쓰", attendStatus = AttendStatus.ATTEND),
+ MemberData(25, "지유쓰", attendStatus = AttendStatus.ATTEND),
+ MemberData(25, "스티브", attendStatus = AttendStatus.ATTEND),
+ MemberData(25, "오션쓰", attendStatus = AttendStatus.ATTEND),
+)
+
+@Composable
+fun MemberLists() {
+ val attendStatusList: List = listOf(
+ Attendance(
+ attendance = "참석",
+ painter = painterResource(id = R.drawable.detail_ic_attend_20dp),
+ memberList = sampleMemberList
+ ),
+ Attendance(
+ attendance = "불참",
+ painter = painterResource(id = R.drawable.detail_ic_absent_20dp),
+ memberList = sampleMemberList
+ ),
+ Attendance(
+ attendance = "지각",
+ painter = painterResource(id = R.drawable.detail_ic_latecomers_20dp),
+ memberList = sampleMemberList
+ ),
+ Attendance(
+ attendance = "미정",
+ painter = painterResource(id = R.drawable.detail_ic_undefined_20dp),
+ memberList = sampleMemberList
+ ),
+ )
+
+ Column {
+ attendStatusList.forEach { attendStatus ->
+ MemberList(
+ title = attendStatus.attendance,
+ painter = attendStatus.painter,
+ memberList = attendStatus.memberList /* ToDo */
+ )
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_attendance
+ )
+ )
+ )
+ }
+ }
+}
+
+@Composable
+private fun MemberList(
+ title: String,
+ painter: Painter,
+ memberList: List
+) {
+ Column {
+ Row(
+ modifier = Modifier.width(dimensionResource(id = R.dimen.width_detail_screen_divider)),
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ text = title,
+ style = MaterialTheme.typography.titleSmall,
+ color = colorResource(R.color.paragraph)
+ )
+ Spacer(
+ modifier = Modifier.size(
+ dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_title_and_icon
+ )
+ )
+ )
+ Image(
+ painter = painter,
+ contentDescription = "",
+ )
+ }
+ Text(
+ text = "20명",
+ style = MaterialTheme.typography.bodySmall,
+ color = colorResource(R.color.gray_500)
+ )
+ }
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_detail_screen_divider_top)
+ )
+ )
+ Divider(
+ modifier = Modifier.width(dimensionResource(id = R.dimen.width_detail_screen_divider)),
+ thickness = dimensionResource(id = R.dimen.width_stroke_0_7dp),
+ color = colorResource(id = R.color.stroke_400)
+ )
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_detail_screen_divider_bottom)
+ )
+ )
+
+ NonLazyGrid(
+ columns = 3,
+ itemCount = memberList.size,
+ modifier = Modifier.width(dimensionResource(id = R.dimen.width_detail_screen_divider)),
+ ) {
+ Member(memberList[it])
+ }
+ }
+}
+
+@Composable
+private fun Member(member: MemberData) {
+ Row(
+ horizontalArrangement = Arrangement.Center
+ ) {
+ Text(
+ text = member.generation.toString() + "기",
+ style = MaterialTheme.typography.bodySmall,
+ color = colorResource(id = R.color.paragraph)
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_member_list_generation_and_name
+ )
+ )
+ )
+ Text(
+ text = member.name,
+ style = MaterialTheme.typography.bodySmall,
+ color = colorResource(id = R.color.paragraph)
+ )
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun ProgramPreview() {
+ MaterialTheme {
+ MemberLists()
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/detail/ProgramDetail.kt b/AOS/app/src/main/java/com/example/eeos/ui/detail/ProgramDetail.kt
new file mode 100644
index 00000000..d59e0770
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/detail/ProgramDetail.kt
@@ -0,0 +1,166 @@
+package com.example.eeos.ui.detail
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Divider
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun ProgramDetail() {
+ Column {
+ Column(
+ horizontalAlignment = Alignment.Start
+ ) {
+ Category()
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_tag_and_post_title
+ )
+ )
+ )
+ Title()
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(
+ id = R.dimen.margin_detail_screen_space_between_subtitle_and_divider
+ )
+ )
+ )
+ }
+ Column {
+ Divider(
+ modifier = Modifier.width(
+ dimensionResource(id = R.dimen.width_detail_screen_divider)
+ ),
+ thickness = dimensionResource(id = R.dimen.width_stroke_0_7dp),
+ color = colorResource(id = R.color.stroke_400)
+ )
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_detail_screen_space_post_content_vertical)
+ )
+ )
+ Row(
+ horizontalArrangement = Arrangement.Start
+ ) {
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_detail_screen_space_post_content_horizontal
+ )
+ )
+ )
+ Content()
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(
+ id = R.dimen.margin_detail_screen_space_post_content_horizontal
+ )
+ )
+ )
+ }
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_detail_screen_space_post_content_vertical)
+ )
+ )
+ }
+ }
+}
+
+@Composable
+private fun Category() {
+ val containerColor = colorResource(R.color.warning_light)
+ val contentColor = colorResource(R.color.warning_strong)
+
+ Button(
+ modifier = Modifier
+ .size(
+ width = dimensionResource(id = R.dimen.width_detail_screen_space_category_chip),
+ height = dimensionResource(id = R.dimen.height_detail_screen_space_category_chip)
+ )
+ .clip(RoundedCornerShape(dimensionResource(id = R.dimen.size_corner_10dp))),
+ onClick = {},
+ enabled = false,
+ colors = ButtonDefaults.buttonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = containerColor,
+ disabledContentColor = contentColor
+ ),
+ border = BorderStroke(
+ width = dimensionResource(id = R.dimen.width_stroke_0_7dp),
+ color = colorResource(R.color.warning_strong)
+ ),
+ contentPadding = PaddingValues(
+ horizontal = dimensionResource(id = R.dimen.padding_values_0dp),
+ vertical = dimensionResource(id = R.dimen.padding_values_0dp)
+ ),
+ ) {
+ Text(
+ text = "주간 발표", /* ToDo */
+ style = MaterialTheme.typography.labelSmall,
+ color = colorResource(R.color.warning_strong)
+ )
+ }
+}
+
+@Composable
+private fun Title() {
+ Text(
+ text = "10월 2주차 주간 발표", /* ToDo */
+ style = MaterialTheme.typography.headlineMedium
+ )
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(id = R.dimen.margin_detail_screen_space_between_title_and_subtitle)
+ )
+ )
+ Text(
+ text = "2023년 10월 6일 (일)", /* ToDo */
+ style = MaterialTheme.typography.bodyLarge
+ )
+}
+
+@Composable
+private fun Content() {
+ Text(
+ text = "샘플 텍스트"/* ToDo */,
+ style = MaterialTheme.typography.bodySmall,
+ modifier = Modifier.width(
+ width = dimensionResource(id = R.dimen.width_detail_screen_divider) - dimensionResource(
+ id = R.dimen.margin_detail_screen_space_post_content_horizontal
+ ) - dimensionResource(
+ id = R.dimen.margin_detail_screen_space_post_content_horizontal
+ )
+ )
+ )
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun ProgramDetailPreview() {
+ MaterialTheme {
+ ProgramDetail()
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/home/CategoryChips.kt b/AOS/app/src/main/java/com/example/eeos/ui/home/CategoryChips.kt
new file mode 100644
index 00000000..b604a149
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/home/CategoryChips.kt
@@ -0,0 +1,128 @@
+package com.example.eeos.ui.home
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.horizontalScroll
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun CategoryChips(categoryChips: List, selectedCategory: MutableState) {
+ Row(
+ modifier = Modifier.horizontalScroll(rememberScrollState())
+ ) {
+ categoryChips.forEach { chipName ->
+ CategoryChip(
+ chipName = chipName,
+ isSelected = chipName == selectedCategory.value,
+ onClick = { selectedCategory.value = chipName }
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(id = R.dimen.margin_home_screen_space_between_categories)
+ )
+ )
+ }
+ }
+}
+
+@Composable
+private fun CategoryChip(
+ chipName: String,
+ isSelected: Boolean,
+ onClick: () -> Unit,
+) {
+ /*val interactionSource = remember { MutableInteractionSource() }
+ val isFocused by interactionSource.collectIsFocusedAsState()*/
+
+ val containerColor = if (isSelected) {
+ colorResource(R.color.paragraph)
+ } else {
+ colorResource(R.color.background)
+ }
+ val contentColor = if (isSelected) {
+ colorResource(R.color.background)
+ } else {
+ colorResource(R.color.gray_500)
+ }
+ val borderStroke = if (isSelected) {
+ BorderStroke(
+ width = dimensionResource(id = R.dimen.size_all_0dp),
+ color = colorResource(id = R.color.transparent)
+ )
+ } else {
+ BorderStroke(
+ width = dimensionResource(id = R.dimen.width_stroke_0_3dp),
+ color = colorResource(id = R.color.stroke_400)
+ )
+ }
+
+ Button(
+ modifier = Modifier.size(
+ width = dimensionResource(id = R.dimen.width_home_screen_category_button),
+ height = dimensionResource(id = R.dimen.height_home_screen_category_button)
+ ),
+ shape = RoundedCornerShape(dimensionResource(id = R.dimen.size_corner_11dp)),
+ colors = ButtonDefaults.buttonColors(
+ containerColor = containerColor,
+ contentColor = contentColor
+ ),
+ onClick = onClick,
+ border = borderStroke,
+ contentPadding = PaddingValues(dimensionResource(id = R.dimen.size_all_0dp))
+ ) {
+ Text(
+ text = chipName,
+ style = MaterialTheme.typography.labelMedium,
+ textAlign = TextAlign.Center
+ )
+ }
+}
+
+@Preview
+@Composable
+private fun TabPreview() {
+ MaterialTheme {
+ CategoryChips(
+ categoryChips = listOf(
+ stringResource(R.string.home_tab_all),
+ stringResource(R.string.home_tab_presentation),
+ stringResource(R.string.home_tab_leaders),
+ stringResource(R.string.home_tab_party_department),
+ stringResource(R.string.home_tab_others)
+ ),
+ selectedCategory = rememberSaveable { mutableStateOf("전체") }
+ )
+ }
+}
+
+@Preview
+@Composable
+private fun ChipPreview() {
+ MaterialTheme {
+ CategoryChip(
+ chipName = "주간 발표",
+ onClick = {},
+ isSelected = true
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/home/HomeScreen.kt b/AOS/app/src/main/java/com/example/eeos/ui/home/HomeScreen.kt
new file mode 100644
index 00000000..c401184a
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/home/HomeScreen.kt
@@ -0,0 +1,134 @@
+package com.example.eeos.ui.home
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+import com.example.eeos.ui.common.EeosTopAppBar
+
+val programLists: List = listOf(
+ ProgramData(
+ date = "2023년 11월 06일 (월)",
+ title = "오늘의 행사 두구두구",
+ category = "주간 발표",
+ isEnd = false
+ ),
+ ProgramData(
+ date = "2023년 11월 06일 (월)",
+ title = "오늘의 행사 두구두구",
+ category = "주간 발표",
+ isEnd = false
+ ),
+ ProgramData(
+ date = "2023년 11월 06일 (월)",
+ title = "오늘의 행사 두구두구",
+ category = "주간 발표",
+ isEnd = false
+ ),
+)
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun HomeScreen(
+ onProgramClick: () -> Unit
+) {
+ val categoryChips: List = listOf(
+ stringResource(R.string.home_tab_all),
+ stringResource(R.string.home_tab_presentation),
+ stringResource(R.string.home_tab_leaders),
+ stringResource(R.string.home_tab_party_department),
+ stringResource(R.string.home_tab_others)
+ )
+ val programStatusChips: List = listOf(
+ stringResource(id = R.string.home_program_status_ing),
+ stringResource(id = R.string.home_program_status_ends)
+ )
+
+ val selectedCategory = rememberSaveable { mutableStateOf(categoryChips[0]) }
+ val selectedProgramStatus = rememberSaveable { mutableStateOf(programStatusChips[0]) }
+
+ Scaffold(
+ topBar = {
+ EeosTopAppBar()
+ },
+ containerColor = colorResource(id = R.color.background)
+ ) { innerPadding ->
+ Row(
+ modifier = Modifier.padding(innerPadding)
+ ) {
+ Spacer(
+ modifier = Modifier.width(
+ width = dimensionResource(id = R.dimen.margin_common_screen)
+ )
+ )
+ Column {
+ Text(
+ text = stringResource(R.string.home_program_list),
+ style = MaterialTheme.typography.headlineSmall,
+ color = colorResource(id = R.color.paragraph)
+ )
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_home_screen_category_vertical
+ )
+ )
+ )
+ CategoryChips(categoryChips = categoryChips, selectedCategory = selectedCategory)
+
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_home_screen_category_vertical
+ )
+ )
+ )
+ ProgramStatusChips(
+ programStatusChips = programStatusChips,
+ selectedProgramStatus = selectedProgramStatus
+ )
+ Spacer(
+ modifier = Modifier.height(
+ height = dimensionResource(
+ id = R.dimen.margin_home_screen_program_status_vertical
+ )
+ )
+ )
+ ProgramLists(
+ programLists = programLists,
+ onProgramClick = onProgramClick
+ )
+ }
+ Spacer(
+ modifier = Modifier.width(
+ width = dimensionResource(id = R.dimen.margin_common_screen)
+ )
+ )
+ }
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun HomeScreenPreview() {
+ MaterialTheme {
+ HomeScreen(
+ onProgramClick = {}
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramData.kt b/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramData.kt
new file mode 100644
index 00000000..1d412ac7
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramData.kt
@@ -0,0 +1,8 @@
+package com.example.eeos.ui.home
+
+data class ProgramData(
+ val date: String,
+ val title: String,
+ val category: String,
+ val isEnd: Boolean
+)
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramLists.kt b/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramLists.kt
new file mode 100644
index 00000000..c5a66423
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramLists.kt
@@ -0,0 +1,79 @@
+package com.example.eeos.ui.home
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.Divider
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun ProgramLists(programLists: List, onProgramClick: () -> Unit) {
+ LazyColumn {
+ items(programLists) { program ->
+ Program(program, onProgramClick)
+ }
+ }
+}
+
+@Composable
+private fun Program(program: ProgramData, onProgramClick: () -> Unit) {
+ Column {
+ Divider(
+ thickness = dimensionResource(id = R.dimen.width_stroke_0_7dp),
+ color = colorResource(id = R.color.stroke_400)
+ )
+ Column(
+ modifier = Modifier
+ .padding(
+ horizontal = dimensionResource(
+ id = R.dimen.padding_home_screen_program_horizontal
+ )
+ )
+ .size(
+ width = dimensionResource(id = R.dimen.width_home_screen_program),
+ height = dimensionResource(id = R.dimen.height_home_screen_program)
+ )
+ .clickable { onProgramClick(/* TODO : programId 넘겨주기*/) },
+ verticalArrangement = Arrangement.Center
+ ) {
+ Text(
+ text = program.date,
+ style = MaterialTheme.typography.bodyMedium,
+ color = colorResource(R.color.paragraph)
+ )
+ Spacer(
+ modifier = Modifier.size(
+ dimensionResource(id = R.dimen.margin_home_screen_space_between_program_texts)
+ )
+ )
+ Text(
+ text = program.title,
+ style = MaterialTheme.typography.titleSmall,
+ color = colorResource(R.color.paragraph)
+ )
+ }
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun ProgramPreview() {
+ MaterialTheme {
+ ProgramLists(
+ programLists = listOf(),
+ onProgramClick = {}
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramStatusChips.kt b/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramStatusChips.kt
new file mode 100644
index 00000000..1f3c1bf8
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/home/ProgramStatusChips.kt
@@ -0,0 +1,90 @@
+package com.example.eeos.ui.home
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun ProgramStatusChips(
+ programStatusChips: List,
+ selectedProgramStatus: MutableState
+) {
+ Row {
+ programStatusChips.forEach { chip ->
+ ProgramStatusChip(
+ chipName = chip,
+ isSelected = chip == selectedProgramStatus.value,
+ onClick = { selectedProgramStatus.value = chip }
+ )
+ Spacer(
+ modifier = Modifier.width(
+ dimensionResource(id = R.dimen.margin_home_screen_space_between_program_status)
+ )
+ )
+ }
+ }
+}
+
+@Composable
+private fun ProgramStatusChip(
+ chipName: String,
+ isSelected: Boolean,
+ onClick: () -> Unit,
+) {
+ /*val interactionSource = remember { MutableInteractionSource() }
+ val isFocused by interactionSource.collectIsFocusedAsState()*/
+
+ val textColor = if (isSelected) {
+ colorResource(R.color.paragraph)
+ } else {
+ colorResource(R.color.gray_500)
+ }
+
+ Text(
+ text = chipName,
+ color = textColor,
+ style = MaterialTheme.typography.titleSmall,
+ modifier = Modifier.clickable {
+ onClick()
+ }
+ )
+}
+
+@Preview
+@Composable
+private fun ProgramStatusChipsPreview() {
+ MaterialTheme {
+ ProgramStatusChips(
+ programStatusChips = listOf(
+ stringResource(id = R.string.home_program_status_ing),
+ stringResource(id = R.string.home_program_status_ends)
+ ),
+ selectedProgramStatus = rememberSaveable { mutableStateOf("진행 중") }
+ )
+ }
+}
+
+@Preview
+@Composable
+private fun ProgramStatusChipPreview() {
+ MaterialTheme {
+ ProgramStatusChip(
+ chipName = "주간 발표",
+ onClick = {},
+ isSelected = true
+ )
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/login/LoginScreen.kt b/AOS/app/src/main/java/com/example/eeos/ui/login/LoginScreen.kt
new file mode 100644
index 00000000..c822b24b
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/login/LoginScreen.kt
@@ -0,0 +1,52 @@
+package com.example.eeos.ui.login
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Button
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.example.eeos.R
+
+@Composable
+fun LoginScreen(
+ onClick: () -> Unit
+) {
+ Box(
+ modifier = Modifier.fillMaxSize(),
+ contentAlignment = Alignment.Center
+ ) {
+ Column {
+ Image(
+ painter = painterResource(id = R.drawable.eeos_logo_symbol),
+ contentDescription = "Logo of EEOS",
+ modifier = Modifier.size(
+ dimensionResource(id = R.dimen.size_common_screen_logo_120dp)
+ )
+ )
+ Button(
+ onClick = onClick
+ ) {
+ Text(
+ text = "SampleButton"
+ )
+ }
+ }
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun LoginScreenPreview() {
+ MaterialTheme {
+ LoginScreen(onClick = {})
+ }
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/theme/Color.kt b/AOS/app/src/main/java/com/example/eeos/ui/theme/Color.kt
new file mode 100644
index 00000000..9f608fd5
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/theme/Color.kt
@@ -0,0 +1,11 @@
+package com.example.eeos.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple80 = Color(0xFFD0BCFF)
+val PurpleGrey80 = Color(0xFFCCC2DC)
+val Pink80 = Color(0xFFEFB8C8)
+
+val Purple40 = Color(0xFF6650a4)
+val PurpleGrey40 = Color(0xFF625b71)
+val Pink40 = Color(0xFF7D5260)
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/theme/Theme.kt b/AOS/app/src/main/java/com/example/eeos/ui/theme/Theme.kt
new file mode 100644
index 00000000..8479eddf
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/theme/Theme.kt
@@ -0,0 +1,69 @@
+package com.example.eeos.ui.theme
+
+import android.app.Activity
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.dynamicDarkColorScheme
+import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalView
+import androidx.core.view.WindowCompat
+
+private val DarkColorScheme = darkColorScheme(
+ primary = Purple80,
+ secondary = PurpleGrey80,
+ tertiary = Pink80
+)
+
+private val LightColorScheme = lightColorScheme(
+ primary = Purple40,
+ secondary = PurpleGrey40,
+ tertiary = Pink40
+
+ /* Other default colors to override
+ background = Color(0xFFFFFBFE),
+ surface = Color(0xFFFFFBFE),
+ onPrimary = Color.White,
+ onSecondary = Color.White,
+ onTertiary = Color.White,
+ onBackground = Color(0xFF1C1B1F),
+ onSurface = Color(0xFF1C1B1F),
+ */
+)
+
+@Composable
+fun EeosTheme(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ // Dynamic color is available on Android 12+
+ dynamicColor: Boolean = true,
+ content: @Composable () -> Unit
+) {
+ val colorScheme = when {
+ dynamicColor -> {
+ val context = LocalContext.current
+ if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
+ }
+
+ darkTheme -> DarkColorScheme
+ else -> LightColorScheme
+ }
+ val view = LocalView.current
+ if (!view.isInEditMode) {
+ SideEffect {
+ val window = (view.context as Activity).window
+ window.statusBarColor = colorScheme.primary.toArgb()
+ WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
+ }
+ }
+
+ MaterialTheme(
+ colorScheme = colorScheme,
+ typography = eeosTypography,
+ content = content
+ )
+}
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/theme/Type.kt b/AOS/app/src/main/java/com/example/eeos/ui/theme/Type.kt
new file mode 100644
index 00000000..32944429
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/theme/Type.kt
@@ -0,0 +1,90 @@
+package com.example.eeos.ui.theme
+
+import androidx.compose.material3.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+import com.example.eeos.R
+
+val Pretendard: FontFamily = FontFamily(
+ Font(R.font.pretendard_black, FontWeight.Black),
+ Font(R.font.pretendard_extrabold, FontWeight.ExtraBold),
+ Font(R.font.pretendard_bold, FontWeight.Bold),
+ Font(R.font.pretendard_semibold, FontWeight.SemiBold),
+ Font(R.font.pretendard_medium, FontWeight.Medium),
+ Font(R.font.pretendard_regular, FontWeight.Normal),
+ Font(R.font.pretendard_light, FontWeight.Light),
+ Font(R.font.pretendard_extralight, FontWeight.ExtraLight),
+ Font(R.font.pretendard_thin, FontWeight.Thin)
+)
+
+val eeosTypography = Typography(
+ headlineMedium = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Bold,
+ fontSize = 24.sp,
+ lineHeight = 32.sp,
+ ),
+ headlineSmall = TextStyle(
+ fontFamily = Pretendard,
+ fontWeight = FontWeight.Bold,
+ fontSize = 22.sp,
+ lineHeight = 28.sp
+ ),
+ titleLarge = TextStyle(
+ fontFamily = Pretendard,
+ fontWeight = FontWeight.Bold,
+ fontSize = 18.sp,
+ lineHeight = 24.sp
+ ),
+ titleMedium = TextStyle(
+ fontFamily = Pretendard,
+ fontWeight = FontWeight.Medium,
+ fontSize = 18.sp,
+ lineHeight = 24.sp
+ ),
+ titleSmall = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Bold,
+ fontSize = 14.sp,
+ lineHeight = 20.sp
+ ),
+ bodyLarge = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 14.sp,
+ lineHeight = 20.7.sp
+ ),
+ bodyMedium = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Medium,
+ fontSize = 14.sp,
+ lineHeight = 20.sp
+ ),
+ bodySmall = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp,
+ lineHeight = 16.sp
+ ),
+ labelLarge = TextStyle(
+ fontFamily = Pretendard,
+ fontWeight = FontWeight.Normal,
+ fontSize = 14.sp,
+ lineHeight = 20.sp
+ ),
+ labelMedium = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 12.sp,
+ lineHeight = 16.sp
+ ),
+ labelSmall = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 10.sp,
+ lineHeight = 16.sp
+ )
+)
diff --git a/AOS/app/src/main/java/com/example/eeos/ui/util/NonLazyGrid.kt b/AOS/app/src/main/java/com/example/eeos/ui/util/NonLazyGrid.kt
new file mode 100644
index 00000000..20946a77
--- /dev/null
+++ b/AOS/app/src/main/java/com/example/eeos/ui/util/NonLazyGrid.kt
@@ -0,0 +1,57 @@
+package com.example.eeos.ui.util
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
+import com.example.eeos.R
+
+@Composable
+fun NonLazyGrid(
+ columns: Int,
+ itemCount: Int,
+ modifier: Modifier = Modifier,
+ content: @Composable (Int) -> Unit
+) {
+ Column(
+ modifier = modifier
+ ) {
+ var rows = (itemCount / columns)
+ if (itemCount.mod(columns) > 0) {
+ rows += 1
+ }
+
+ for (rowId in 0 until rows) {
+ val firstIndex = rowId * columns
+
+ Row {
+ for (columnId in 0 until columns) {
+ val index = firstIndex + columnId
+
+ Box(
+ modifier = Modifier.fillMaxWidth()
+ .weight(1f),
+ contentAlignment = Alignment.Center
+ ) {
+ if (index < itemCount) {
+ content(index)
+ }
+ }
+ }
+ }
+ Spacer(
+ modifier = Modifier.height(
+ dimensionResource(
+ R.dimen.margin_detail_screen_space_between_member_list_content
+ )
+ )
+ )
+ }
+ }
+}
diff --git a/AOS/app/src/main/res/drawable/common_mypage_button.xml b/AOS/app/src/main/res/drawable/common_mypage_button.xml
new file mode 100644
index 00000000..260a288d
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/common_mypage_button.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/AOS/app/src/main/res/drawable/detail_bottom_sheet_drag_handle.xml b/AOS/app/src/main/res/drawable/detail_bottom_sheet_drag_handle.xml
new file mode 100644
index 00000000..054107cb
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/detail_bottom_sheet_drag_handle.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/AOS/app/src/main/res/drawable/detail_ic_absent_20dp.xml b/AOS/app/src/main/res/drawable/detail_ic_absent_20dp.xml
new file mode 100644
index 00000000..380f97d1
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/detail_ic_absent_20dp.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/detail_ic_attend_20dp.xml b/AOS/app/src/main/res/drawable/detail_ic_attend_20dp.xml
new file mode 100644
index 00000000..7c565330
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/detail_ic_attend_20dp.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/detail_ic_latecomers_20dp.xml b/AOS/app/src/main/res/drawable/detail_ic_latecomers_20dp.xml
new file mode 100644
index 00000000..fb867a64
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/detail_ic_latecomers_20dp.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/detail_ic_undefined_20dp.xml b/AOS/app/src/main/res/drawable/detail_ic_undefined_20dp.xml
new file mode 100644
index 00000000..5e665746
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/detail_ic_undefined_20dp.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/eeos_launcher_foreground.xml b/AOS/app/src/main/res/drawable/eeos_launcher_foreground.xml
new file mode 100644
index 00000000..7ab50e58
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/eeos_launcher_foreground.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/eeos_logo_monogram.xml b/AOS/app/src/main/res/drawable/eeos_logo_monogram.xml
new file mode 100644
index 00000000..4c1baf72
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/eeos_logo_monogram.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/eeos_logo_symbol.xml b/AOS/app/src/main/res/drawable/eeos_logo_symbol.xml
new file mode 100644
index 00000000..2c119073
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/eeos_logo_symbol.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/login_button.xml b/AOS/app/src/main/res/drawable/login_button.xml
new file mode 100644
index 00000000..55c4aca6
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/login_button.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AOS/app/src/main/res/drawable/memberstatusdialog_logoutbutton_24dp.xml b/AOS/app/src/main/res/drawable/memberstatusdialog_logoutbutton_24dp.xml
new file mode 100644
index 00000000..2006438a
--- /dev/null
+++ b/AOS/app/src/main/res/drawable/memberstatusdialog_logoutbutton_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/AOS/app/src/main/res/font/pretendard_black.ttf b/AOS/app/src/main/res/font/pretendard_black.ttf
new file mode 100644
index 00000000..587556de
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_black.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_bold.ttf b/AOS/app/src/main/res/font/pretendard_bold.ttf
new file mode 100644
index 00000000..208b418f
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_bold.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_extrabold.ttf b/AOS/app/src/main/res/font/pretendard_extrabold.ttf
new file mode 100644
index 00000000..0e24213c
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_extrabold.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_extralight.ttf b/AOS/app/src/main/res/font/pretendard_extralight.ttf
new file mode 100644
index 00000000..939fc344
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_extralight.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_light.ttf b/AOS/app/src/main/res/font/pretendard_light.ttf
new file mode 100644
index 00000000..9b162ae3
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_light.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_medium.ttf b/AOS/app/src/main/res/font/pretendard_medium.ttf
new file mode 100644
index 00000000..46ea47d9
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_medium.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_regular.ttf b/AOS/app/src/main/res/font/pretendard_regular.ttf
new file mode 100644
index 00000000..5017814e
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_regular.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_semibold.ttf b/AOS/app/src/main/res/font/pretendard_semibold.ttf
new file mode 100644
index 00000000..08523727
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_semibold.ttf differ
diff --git a/AOS/app/src/main/res/font/pretendard_thin.ttf b/AOS/app/src/main/res/font/pretendard_thin.ttf
new file mode 100644
index 00000000..53467f55
Binary files /dev/null and b/AOS/app/src/main/res/font/pretendard_thin.ttf differ
diff --git a/AOS/app/src/main/res/mipmap-anydpi-v26/eeos_launcher.xml b/AOS/app/src/main/res/mipmap-anydpi-v26/eeos_launcher.xml
new file mode 100644
index 00000000..087afc00
--- /dev/null
+++ b/AOS/app/src/main/res/mipmap-anydpi-v26/eeos_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/main/res/mipmap-anydpi-v26/eeos_launcher_round.xml b/AOS/app/src/main/res/mipmap-anydpi-v26/eeos_launcher_round.xml
new file mode 100644
index 00000000..087afc00
--- /dev/null
+++ b/AOS/app/src/main/res/mipmap-anydpi-v26/eeos_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/main/res/mipmap-hdpi/eeos_launcher.png b/AOS/app/src/main/res/mipmap-hdpi/eeos_launcher.png
new file mode 100644
index 00000000..9128e35b
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-hdpi/eeos_launcher.png differ
diff --git a/AOS/app/src/main/res/mipmap-hdpi/eeos_launcher_round.png b/AOS/app/src/main/res/mipmap-hdpi/eeos_launcher_round.png
new file mode 100644
index 00000000..d0307173
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-hdpi/eeos_launcher_round.png differ
diff --git a/AOS/app/src/main/res/mipmap-mdpi/eeos_launcher.png b/AOS/app/src/main/res/mipmap-mdpi/eeos_launcher.png
new file mode 100644
index 00000000..185c0134
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-mdpi/eeos_launcher.png differ
diff --git a/AOS/app/src/main/res/mipmap-mdpi/eeos_launcher_round.png b/AOS/app/src/main/res/mipmap-mdpi/eeos_launcher_round.png
new file mode 100644
index 00000000..8ddba0bd
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-mdpi/eeos_launcher_round.png differ
diff --git a/AOS/app/src/main/res/mipmap-xhdpi/eeos_launcher.png b/AOS/app/src/main/res/mipmap-xhdpi/eeos_launcher.png
new file mode 100644
index 00000000..0387e7d1
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-xhdpi/eeos_launcher.png differ
diff --git a/AOS/app/src/main/res/mipmap-xhdpi/eeos_launcher_round.png b/AOS/app/src/main/res/mipmap-xhdpi/eeos_launcher_round.png
new file mode 100644
index 00000000..6a64f4cd
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-xhdpi/eeos_launcher_round.png differ
diff --git a/AOS/app/src/main/res/mipmap-xxhdpi/eeos_launcher.png b/AOS/app/src/main/res/mipmap-xxhdpi/eeos_launcher.png
new file mode 100644
index 00000000..30b3888f
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-xxhdpi/eeos_launcher.png differ
diff --git a/AOS/app/src/main/res/mipmap-xxhdpi/eeos_launcher_round.png b/AOS/app/src/main/res/mipmap-xxhdpi/eeos_launcher_round.png
new file mode 100644
index 00000000..0d9f326f
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-xxhdpi/eeos_launcher_round.png differ
diff --git a/AOS/app/src/main/res/mipmap-xxxhdpi/eeos_launcher.png b/AOS/app/src/main/res/mipmap-xxxhdpi/eeos_launcher.png
new file mode 100644
index 00000000..83ebd123
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-xxxhdpi/eeos_launcher.png differ
diff --git a/AOS/app/src/main/res/mipmap-xxxhdpi/eeos_launcher_round.png b/AOS/app/src/main/res/mipmap-xxxhdpi/eeos_launcher_round.png
new file mode 100644
index 00000000..19f18a6c
Binary files /dev/null and b/AOS/app/src/main/res/mipmap-xxxhdpi/eeos_launcher_round.png differ
diff --git a/AOS/app/src/main/res/values/colors.xml b/AOS/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..a3c6f424
--- /dev/null
+++ b/AOS/app/src/main/res/values/colors.xml
@@ -0,0 +1,50 @@
+
+
+
+ #FF000000
+ #FFFFFFFF
+ #00FFFFFF
+
+
+
+
+ #FFFFFFFE
+ #FF2D334A
+ #FFFFD803
+ #FFE3F6F5
+ #FFFF6464
+
+
+
+ #FFBAE8E8
+ #FF689696
+
+
+
+ #FFFAFAFA
+ #FFD9D9D9
+ #FFA9A7B3
+ #FF595959
+
+
+
+ #FFD4D3D9
+ #FFA9A7B3
+ #FF272343
+
+
+
+ #FF00A500
+ #FF00DE52
+ #FFEEFAEE
+
+ #FFFF6530
+ #FFFFE9E4
+
+ #FFEFB300
+ #FFFFC51A
+ #FFFFF7E2
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/main/res/values/dimension.xml b/AOS/app/src/main/res/values/dimension.xml
new file mode 100644
index 00000000..32da9a35
--- /dev/null
+++ b/AOS/app/src/main/res/values/dimension.xml
@@ -0,0 +1,117 @@
+
+
+
+ 0dp
+
+
+
+ 120dp
+ 16dp
+ 13dp
+ 3dp
+
+
+
+ 25dp
+ 29dp
+
+ 10dp
+ 74dp
+ 33dp
+
+ 19dp
+
+ 7dp
+ 318dp
+ 94dp
+ 28dp
+
+
+
+ 300dp
+ 238dp
+ 17dp
+ 15dp
+ 16dp
+
+ 88dp
+ 76dp
+ 17dp
+ 15dp
+
+ 127dp
+ 60dp
+ 1dp
+ 14dp
+ 15dp
+
+
+
+ 85dp
+ 30dp
+
+ 13dp
+ 10dp
+ 10dp
+ 350dp
+ 20dp
+ 20dp
+ 16dp
+
+ 5dp
+ 10dp
+ 20dp
+ 16dp
+ 5dp
+ 30dp
+ 95dp
+
+
+
+ 95dp
+ 20dp
+
+ 7dp
+ 20dp
+ 12dp
+ 12dp
+
+ 12dp
+
+ 86dp
+ 40dp
+ 200dp
+ 43dp
+
+ 30dp
+
+
+
+
+
+ 10dp
+ 11dp
+ 20dp
+ 25dp
+
+
+
+
+ 0.3dp
+ 0.7dp
+ 1dp
+ 1.2dp
+ 1.5dp
+
+
+
+
+ 0dp
+ 7dp
+ 10dp
+ 15dp
+ 30dp
+ 35dp
+
+
+
diff --git a/AOS/app/src/main/res/values/eeos_launcher_background.xml b/AOS/app/src/main/res/values/eeos_launcher_background.xml
new file mode 100644
index 00000000..720b6de9
--- /dev/null
+++ b/AOS/app/src/main/res/values/eeos_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFE
+
\ No newline at end of file
diff --git a/AOS/app/src/main/res/values/strings.xml b/AOS/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..e11bf3f4
--- /dev/null
+++ b/AOS/app/src/main/res/values/strings.xml
@@ -0,0 +1,52 @@
+
+
+ EEOS
+
+
+
+
+ 행사 목록
+
+ 진행 중
+ 완료
+
+ 전체
+ 주간 발표
+ 회장단
+ 행사부
+ 기타 행사
+
+
+
+
+ 본인의 회원 상태를 선택해 주세요.
+ AM
+ RM&DM
+ CM
+ OB
+
+
+
+
+ 참석
+ 불참
+ 지각
+ 미정
+
+
+
+
+ %1$s 님
+ 본 행사와 관련 없음
+ 출석 체크 해주세요!
+ 수요 조사 해주세요!
+ 본인의 출석 상태를 선택해 주세요.
+
+
+
+ 로그아웃 하기
+
+ Bottom Sheet를 올리면 출석 상태를 선택할 수 있습니다.
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/main/res/values/themes.xml b/AOS/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..3290e720
--- /dev/null
+++ b/AOS/app/src/main/res/values/themes.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/main/res/xml/backup_rules.xml b/AOS/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..fa0f996d
--- /dev/null
+++ b/AOS/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/main/res/xml/data_extraction_rules.xml b/AOS/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..9ee9997b
--- /dev/null
+++ b/AOS/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AOS/app/src/test/java/com/example/eeos/ExampleUnitTest.kt b/AOS/app/src/test/java/com/example/eeos/ExampleUnitTest.kt
new file mode 100644
index 00000000..61ff4377
--- /dev/null
+++ b/AOS/app/src/test/java/com/example/eeos/ExampleUnitTest.kt
@@ -0,0 +1,16 @@
+package com.example.eeos
+
+import org.junit.Assert.*
+import org.junit.Test
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
diff --git a/AOS/build.gradle b/AOS/build.gradle
new file mode 100644
index 00000000..ab91fadf
--- /dev/null
+++ b/AOS/build.gradle
@@ -0,0 +1,7 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '8.0.1' apply false
+ id 'com.android.library' version '8.0.1' apply false
+ id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
+ id "org.jlleitschuh.gradle.ktlint" version '11.6.1'
+}
\ No newline at end of file
diff --git a/AOS/gradle.properties b/AOS/gradle.properties
new file mode 100644
index 00000000..c22da573
--- /dev/null
+++ b/AOS/gradle.properties
@@ -0,0 +1,24 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.enableJetifier=true
\ No newline at end of file
diff --git a/AOS/gradle/wrapper/gradle-wrapper.jar b/AOS/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/AOS/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/AOS/gradle/wrapper/gradle-wrapper.properties b/AOS/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..759685cf
--- /dev/null
+++ b/AOS/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Nov 02 11:32:05 KST 2023
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/AOS/gradlew b/AOS/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/AOS/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/AOS/gradlew.bat b/AOS/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/AOS/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/AOS/settings.gradle b/AOS/settings.gradle
new file mode 100644
index 00000000..e12499dd
--- /dev/null
+++ b/AOS/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "eeos"
+include ':app'