瀏覽代碼

admin page in progress

dola 1 年之前
父節點
當前提交
7c1f833080

+ 8 - 0
app/src/main/java/com/sambath/kunkhmer/app/AdminActivity.kt

@@ -3,14 +3,22 @@ package com.sambath.kunkhmer.app
 import androidx.appcompat.app.AppCompatActivity
 import android.os.Bundle
 import androidx.navigation.findNavController
+import androidx.navigation.ui.setupWithNavController
+import com.google.android.material.bottomnavigation.BottomNavigationView
 import com.sambath.kunkhmer.R
 import kotlinx.android.synthetic.main.app_bar_boxing.iv_account
 
 class AdminActivity : AppCompatActivity() {
+    lateinit var navView: BottomNavigationView
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.activity_admin)
 
+        navView =  findViewById<BottomNavigationView>(R.id.nav_view)
+        val navController = findNavController(R.id.nav_host_fragment_activity_main)
+        navView.setupWithNavController(navController)
+
         iv_account.setOnClickListener{
             findNavController(R.id.nav_host_fragment_activity_main).navigate(R.id.navigation_account)
         }

+ 46 - 0
app/src/main/java/com/sambath/kunkhmer/remote/NewsDataModel.kt

@@ -34,3 +34,49 @@ data class News(
     @Json(name = "filename")
     val filename: String?,
 )
+
+// ---- create request
+
+@JsonClass(generateAdapter = true)
+class CreateNewsRequest(
+    @Json(name = "title")
+    val title: String,
+    @Json(name = "desc")
+    val desc: String,
+    @Json(name = "upload")
+    val upload: String
+)
+
+@JsonClass(generateAdapter = true)
+data class CreateNewsResponse(
+    @Json(name = "code")
+    val resultCode: Int,
+    @Json(name = "message")
+    val message: ResponseMessage,
+    @Json(name = "data")
+    val data: NewsCreatedData?
+)
+
+@JsonClass(generateAdapter = true)
+data class NewsCreatedData(
+    @Json(name = "new")
+    val obj: CreatedNews,
+)
+
+@JsonClass(generateAdapter = true)
+data class CreatedNews(
+    @Json(name = "_id")
+    val id: String,
+    @Json(name = "viewer")
+    val viewer: Int,
+    @Json(name = "title")
+    val title: String,
+    @Json(name = "desc")
+    val desc: String,
+    @Json(name = "createdAt")
+    val createdAt: String,
+    @Json(name = "updatedAt")
+    val updatedAt: String,
+    @Json(name = "__v")
+    val _v: Int,
+)

+ 3 - 0
app/src/main/java/com/sambath/kunkhmer/remote/service/ApiService.kt

@@ -38,6 +38,9 @@ interface ApiService {
 
     @POST("/v1/users/get")
     fun getCurrentUser(): Single<CurrentUserResponse>
+
+    @POST("/v1/new/create")
+    fun createNews(@Body createNewsRequest: CreateNewsRequest): Single<CreateNewsResponse>
     ///---------------------------------------------------------
 
     @POST("/v1/api/user/changepassword")

+ 68 - 38
app/src/main/java/com/sambath/kunkhmer/screen/news/NewsAdminFragment.kt

@@ -1,60 +1,90 @@
 package com.sambath.kunkhmer.screen.news
 
+import android.app.Activity
+import android.content.Intent
+import android.net.Uri
 import android.os.Bundle
 import androidx.fragment.app.Fragment
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.Toast
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.navigation.findNavController
 import com.sambath.kunkhmer.R
+import com.sambath.kunkhmer.app.App
+import com.sambath.kunkhmer.remote.CreateNewsRequest
+import kotlinx.android.synthetic.main.fragment_news_admin.view.et_desc
+import kotlinx.android.synthetic.main.fragment_news_admin.view.et_title
+import kotlinx.android.synthetic.main.fragment_news_admin.view.submitButton
+import kotlinx.android.synthetic.main.fragment_news_admin.view.uploadButton
+import kotlinx.android.synthetic.main.fragment_news_admin.view.uploadedImageView
+import androidx.navigation.findNavController
 
-// TODO: Rename parameter arguments, choose names that match
-// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
-private const val ARG_PARAM1 = "param1"
-private const val ARG_PARAM2 = "param2"
-
-/**
- * A simple [Fragment] subclass.
- * Use the [NewsAdminFragment.newInstance] factory method to
- * create an instance of this fragment.
- */
 class NewsAdminFragment : Fragment() {
-    // TODO: Rename and change types of parameters
-    private var param1: String? = null
-    private var param2: String? = null
+    private var _root: View? = null
+    private val binding get() = _root!!
+    private lateinit var newsViewModel: NewsViewModel
+    private var imageUri: Uri? = null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        arguments?.let {
-            param1 = it.getString(ARG_PARAM1)
-            param2 = it.getString(ARG_PARAM2)
+    }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+        _root = inflater.inflate(R.layout.fragment_news_admin, container, false)
+
+        newsViewModel = NewsViewModel(App.injectApiService(), App.injectPrefHelper())
+        newsViewModel.state.observe(viewLifecycleOwner, androidx.lifecycle.Observer {
+            render(it)
+        })
+        binding.uploadButton.setOnClickListener {
+            openImagePicker()
+        }
+
+        binding.submitButton.setOnClickListener{
+            // You can store the image URI as a string in your CreateNewsRequest object
+            val createNewsRequest = CreateNewsRequest(
+                binding.et_title.text.toString(),
+                binding.et_desc.text.toString(),
+                imageUri.toString()
+            )
+
+            newsViewModel.createNews(createNewsRequest.title, createNewsRequest.desc, createNewsRequest.upload)
         }
+
+        return binding;
     }
 
-    override fun onCreateView(
-        inflater: LayoutInflater, container: ViewGroup?,
-        savedInstanceState: Bundle?
-    ): View? {
-        // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.fragment_news_admin, container, false)
+    private fun render(state: NewsViewState) {
+        if (state.isLoginSuccess) {
+            Toast.makeText(context, "Create Success...", Toast.LENGTH_LONG).show()
+
+            binding.et_title.setText("")
+            binding.et_desc.setText("")
+            binding.uploadedImageView.setImageDrawable(null)
+        }
+        // Other state handling...
     }
 
-    companion object {
-        /**
-         * Use this factory method to create a new instance of
-         * this fragment using the provided parameters.
-         *
-         * @param param1 Parameter 1.
-         * @param param2 Parameter 2.
-         * @return A new instance of fragment NewsAdminFragment.
-         */
-        // TODO: Rename and change types and number of parameters
-        @JvmStatic
-        fun newInstance(param1: String, param2: String) =
-            NewsAdminFragment().apply {
-                arguments = Bundle().apply {
-                    putString(ARG_PARAM1, param1)
-                    putString(ARG_PARAM2, param2)
+    private val imagePicker: ActivityResultLauncher<Intent> =
+        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+            if (result.resultCode == Activity.RESULT_OK) {
+                val data: Intent? = result.data
+                if (data != null) {
+                    imageUri = data.data // The URI of the selected image
+                    if (imageUri != null) {
+                        // Load and display the selected image in the ImageView
+                        binding.uploadedImageView.setImageURI(imageUri)
+                    }
                 }
             }
+        }
+
+    private fun openImagePicker() {
+        val intent = Intent(Intent.ACTION_GET_CONTENT)
+        intent.type = "image/*"
+        imagePicker.launch(intent)
     }
 }

+ 35 - 4
app/src/main/java/com/sambath/kunkhmer/screen/news/NewsViewModel.kt

@@ -1,12 +1,18 @@
 package com.sambath.kunkhmer.screen.news
 
+import android.util.Log
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import com.sambath.kunkhmer.app.getErrorCode
 import com.sambath.kunkhmer.base.BaseViewModel
+import com.sambath.kunkhmer.remote.CreateNewsRequest
+import com.sambath.kunkhmer.remote.CreatedNews
 import com.sambath.kunkhmer.remote.HighlightData
+import com.sambath.kunkhmer.remote.LoginRequest
 import com.sambath.kunkhmer.remote.NewsData
 import com.sambath.kunkhmer.remote.service.ApiService
+import com.sambath.kunkhmer.util.Const
+import com.sambath.kunkhmer.util.ModelPreferencesManager
 import com.sambath.kunkhmer.util.PrefHelper
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.schedulers.Schedulers
@@ -18,15 +24,16 @@ data class NewsViewState(
     val isLoginSuccess: Boolean = false,
     val error: String? = null,
     val newsData: NewsData? = null,
-    val highlightData: HighlightData? = null
+    val highlightData: HighlightData? = null,
+    val createdNewsData: CreatedNews? = null
 )
 
-class NewsViewModel(val apiService: ApiService, val prefHelper: PrefHelper) : BaseViewModel()  {
+class NewsViewModel(val apiService: ApiService, val prefHelper: PrefHelper) : BaseViewModel() {
     private val _state = MutableLiveData(NewsViewState())
     val state: LiveData<NewsViewState> = _state
     private fun prev() = _state.value!!
 
-    fun getNews(){
+    fun getNews() {
         if (_state.value!!.isProgress) return
         _state.value = prev().copy(isProgress = true)
 
@@ -49,7 +56,7 @@ class NewsViewModel(val apiService: ApiService, val prefHelper: PrefHelper) : Ba
         )
     }
 
-    fun getHighlight(){
+    fun getHighlight() {
         if (_state.value!!.isProgress) return
         _state.value = prev().copy(isProgress = true)
 
@@ -71,4 +78,28 @@ class NewsViewModel(val apiService: ApiService, val prefHelper: PrefHelper) : Ba
                 })
         )
     }
+
+    fun createNews(title: String, desc: String, upload: String) {
+        if (_state.value!!.isProgress) return
+        val request = CreateNewsRequest(title, desc, upload)
+        _state.value = prev().copy(isProgress = true)
+
+        disposables.add(
+            apiService.createNews(request)
+                .timeout(10, TimeUnit.SECONDS)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe({
+                    Log.d("login", it.toString())
+                    if (it.resultCode == 1) {
+                        _state.value = prev().copy(isProgress = false, isLoginSuccess = true)
+                    } else {
+                        _state.value = prev().copy(isProgress = false, error = "[${it.message.description}]")
+                    }
+                }, {
+                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ " + it.getErrorCode()
+                    _state.value = prev().copy(isProgress = false, error = message)
+                })
+        )
+    }
 }

+ 72 - 8
app/src/main/res/layout/fragment_news_admin.xml

@@ -1,14 +1,78 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:context=".screen.news.NewsAdminFragment">
+    android:background="@color/color_black"
+    android:orientation="vertical"
+    android:padding="10dp">
 
-    <!-- TODO: Update blank fragment layout -->
-    <TextView
+    <com.google.android.material.textfield.TextInputLayout
+        android:id="@+id/til_title"
+        style="@style/BoxInputLayout"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:text="@string/hello_blank_fragment" />
+        android:layout_height="48dp"
+        android:layout_below="@id/tv_username"
+        app:endIconMode="clear_text"
+        app:hintEnabled="false">
 
-</FrameLayout>
+        <androidx.appcompat.widget.AppCompatEditText
+            android:id="@+id/et_title"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@color/color_white"
+            android:hint="@string/hint_title"
+            android:inputType="text"
+            android:maxLength="50"
+            android:padding="0dp" />
+    </com.google.android.material.textfield.TextInputLayout>
+
+    <com.google.android.material.textfield.TextInputLayout
+        android:id="@+id/til_desc"
+        style="@style/BoxInputLayout"
+        android:layout_width="match_parent"
+        android:layout_height="200dp"
+        android:layout_below="@id/tv_username"
+        app:endIconMode="clear_text"
+        app:hintEnabled="false">
+
+        <androidx.appcompat.widget.AppCompatEditText
+            android:id="@+id/et_desc"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@color/color_white"
+            android:gravity="top"
+            android:hint="@string/hint_desc"
+            android:inputType="text"
+            android:maxLength="50"
+            android:padding="0dp" />
+    </com.google.android.material.textfield.TextInputLayout>
+
+    <Button
+        android:id="@+id/uploadButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginBottom="16dp"
+        android:paddingStart="16dp"
+        android:paddingEnd="16dp"
+        android:text="Upload Image" />
+
+    <ImageView
+        android:id="@+id/uploadedImageView"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:layout_gravity="center"
+        android:layout_marginBottom="16dp"
+        android:background="@color/color_gray_300"
+        android:scaleType="centerCrop" />
+
+    <Button
+        android:id="@+id/submitButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:paddingStart="16dp"
+        android:paddingEnd="16dp"
+        android:text="Submit" />
+</LinearLayout>

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -98,4 +98,6 @@
     <string name="copyright_text"><![CDATA[Copyright 2023 HAHA SUPER FIGHT & GYM]]></string>
     <string name="member_since">Member since</string>
     <string name="English">English</string>
+    <string name="hint_title">Title</string>
+    <string name="hint_desc">Description</string>
 </resources>