diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9b58c9af6f55082849eae8879220ecfb053a4d09..5358e5240b825a51ab4f0a03b896ed45accdc1a1 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -59,6 +59,24 @@ dependencies {
     implementation("com.squareup.retrofit2:converter-gson:2.9.0")
     implementation("com.squareup.okhttp3:logging-interceptor:4.2.0")
     implementation("androidx.security:security-crypto:1.1.0-alpha03")
+
+
+    // Scan Feature
+    // CameraX core library using the camera2 implementation
+    val camerax_version = "1.3.2"
+    // The following line is optional, as the core library is included indirectly by camera-camera2
+    implementation("androidx.camera:camera-core:${camerax_version}")
+    implementation("androidx.camera:camera-camera2:${camerax_version}")
+    // If you want to additionally use the CameraX Lifecycle library
+    implementation("androidx.camera:camera-lifecycle:${camerax_version}")
+    // If you want to additionally use the CameraX VideoCapture library
+    implementation("androidx.camera:camera-video:${camerax_version}")
+    // If you want to additionally use the CameraX View class
+    implementation("androidx.camera:camera-view:${camerax_version}")
+    // If you want to additionally use the CameraX Extensions library
+    implementation("androidx.camera:camera-extensions:${camerax_version}")
+    implementation("androidx.camera:camera-view:${camerax_version}")
+
     testImplementation("junit:junit:4.13.2")
     androidTestImplementation("androidx.test.ext:junit:1.1.5")
     androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f79b02642e970e47f63117dc8684329efaaa4df6..c7b067810ce14775390971a4815c900f1cbef22b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,12 @@
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
+    xmlns:tools="http://schemas.android.com/tools">
+    <uses-feature android:name="android.hardware.camera.any" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+        android:maxSdkVersion="32" />
+
 
     <application
         android:allowBackup="true"
diff --git a/app/src/main/java/com/example/tubespbd/ui/scan/CameraHandler.kt b/app/src/main/java/com/example/tubespbd/ui/scan/CameraHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..582e89f52d9ea4a8355a69d030f68a1287395e9d
--- /dev/null
+++ b/app/src/main/java/com/example/tubespbd/ui/scan/CameraHandler.kt
@@ -0,0 +1,92 @@
+import android.content.Context
+import android.net.Uri
+import android.util.Log
+import androidx.camera.core.CameraSelector
+import androidx.camera.core.Preview
+import androidx.camera.core.ImageCapture
+import androidx.camera.core.ImageCaptureException
+import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.LifecycleOwner
+import com.example.tubespbd.R
+import com.example.tubespbd.databinding.FragmentScanBinding
+import com.google.common.util.concurrent.ListenableFuture
+import java.io.File
+import java.text.SimpleDateFormat
+import java.util.Locale
+
+class CameraHandler(
+    private val context: Context,
+    private val lifecycleOwner: LifecycleOwner,
+    private val binding: FragmentScanBinding) {
+
+    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
+    private lateinit var imageCapture: ImageCapture
+
+    fun startCamera() {
+        // Initialize Preview
+        cameraProviderFuture = ProcessCameraProvider.getInstance(context)
+        cameraProviderFuture.addListener({
+            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
+            bindPreview(cameraProvider)
+        }, ContextCompat.getMainExecutor(context))
+
+        imageCapture = ImageCapture.Builder()
+            .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
+            // Add more configuration options here if needed
+            .build()
+
+    }
+
+    private fun bindPreview(cameraProvider: ProcessCameraProvider) {
+        val previewView = binding.previewView
+        val preview : Preview = Preview.Builder().build()
+        preview.setSurfaceProvider(previewView.surfaceProvider)
+
+        val cameraSelector =  CameraSelector.DEFAULT_BACK_CAMERA
+
+        try {
+            cameraProvider.unbindAll()
+            cameraProvider.bindToLifecycle(
+                lifecycleOwner,
+                cameraSelector,
+                preview,
+                imageCapture)
+        } catch (exc: Exception) {
+            Log.e("CameraHandler", "Use case binding failed", exc)
+        }
+    }
+
+    fun takePicture() {
+        val outputFileOptions = ImageCapture.OutputFileOptions.Builder(getOutputFile()).build()
+        imageCapture.takePicture(
+            outputFileOptions,
+            ContextCompat.getMainExecutor(context),
+            object : ImageCapture.OnImageSavedCallback {
+                override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
+                    val savedUri = outputFileResults.savedUri ?: Uri.fromFile(getOutputFile())
+                    Log.d("CameraHandler", "Photo capture succeeded: $savedUri")
+                }
+
+                override fun onError(exception: ImageCaptureException) {
+                    Log.e("CameraHandler", "Photo capture failed: ${exception.message}", exception)
+                }
+            }
+        )
+    }
+
+    private fun getOutputFile(): File {
+        val mediaDir = context.externalMediaDirs.firstOrNull()?.let {
+            File(it, context.resources.getString(R.string.app_name)).apply { mkdirs() }
+        }
+        val outputDirectory = if (mediaDir != null && mediaDir.exists()) mediaDir else context.filesDir
+        val fileName = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS", Locale.US)
+            .format(System.currentTimeMillis()) + ".jpg"
+        return File(outputDirectory, fileName)
+    }
+
+//    private fun showPicture(): File {
+//
+//    }
+
+}
diff --git a/app/src/main/java/com/example/tubespbd/ui/scan/ScanFragment.kt b/app/src/main/java/com/example/tubespbd/ui/scan/ScanFragment.kt
index 09f1f16117954647e1c648373e4ab83642956b6d..792dc4a5c14372f8d6f972b6fd2db663cd518ff6 100644
--- a/app/src/main/java/com/example/tubespbd/ui/scan/ScanFragment.kt
+++ b/app/src/main/java/com/example/tubespbd/ui/scan/ScanFragment.kt
@@ -1,34 +1,89 @@
 package com.example.tubespbd.ui.scan
 
+import CameraHandler
+import android.Manifest
+import android.content.pm.PackageManager
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import android.widget.TextView
+import android.widget.Toast
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.ViewModelProvider
 import com.example.tubespbd.databinding.FragmentScanBinding
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
 
 class ScanFragment : Fragment() {
     private var _binding: FragmentScanBinding? = null
+    private lateinit var cameraHandler: CameraHandler
 
     private val binding get() = _binding!!
+
+    // On Create Function
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?
     ): View {
         val scanViewModel =
-            ViewModelProvider(this).get(ScanViewModel::class.java)
+            ViewModelProvider(this)[ScanViewModel::class.java]
         _binding = FragmentScanBinding.inflate(inflater, container, false)
+        _binding?.let {
+            cameraHandler = CameraHandler(requireContext(), viewLifecycleOwner, it)
+        }
         val root: View = binding.root
-        val textView: TextView = binding.textScan
+//        val textView: TextView = binding.textScan
         scanViewModel.text.observe(viewLifecycleOwner){
-            textView.text = it
+//            textView.text = it
         }
         return root
     }
 
+    // On View Created Function, for permission after view is made
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        if (allPermissionsGranted()) {
+            cameraHandler.startCamera()
+            binding.captureButton.setOnClickListener {
+                cameraHandler.takePicture()
+            }
+        } else {
+            ActivityCompat.requestPermissions(
+                requireActivity(), REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
+            )
+        }
+    }
+
+    override fun onRequestPermissionsResult(
+        requestCode: Int,
+        permissions: Array<String>,
+        grantResults: IntArray
+    ) {
+        if (requestCode == REQUEST_CODE_PERMISSIONS) {
+            if (allPermissionsGranted()) {
+                cameraHandler.startCamera()
+            } else {
+                Toast.makeText(
+                    context,
+                    "Permissions not granted by the user.",
+                    Toast.LENGTH_SHORT
+                ).show()
+            }
+        }
+    }
+
+    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
+        ContextCompat.checkSelfPermission(
+            requireContext(), it) == PackageManager.PERMISSION_GRANTED
+    }
+
+    companion object {
+        private const val REQUEST_CODE_PERMISSIONS = 10
+        private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
+    }
+
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
diff --git a/app/src/main/java/com/example/tubespbd/ui/scan/ScanViewModel.kt b/app/src/main/java/com/example/tubespbd/ui/scan/ScanViewModel.kt
index 6c61fd896fc754769bf422c009b8bd86f0ab7c46..ec4863c5d8e2c118c9ed7f44a610c0fba9b6a92f 100644
--- a/app/src/main/java/com/example/tubespbd/ui/scan/ScanViewModel.kt
+++ b/app/src/main/java/com/example/tubespbd/ui/scan/ScanViewModel.kt
@@ -4,8 +4,9 @@ import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 
 class ScanViewModel : ViewModel(){
+
     private val _text = MutableLiveData<String>().apply {
-        value = "This is scan fragment"
+        value = "Pindai strukmu!"
     }
     val text: LiveData<String> = _text
 }
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_scan.xml b/app/src/main/res/layout/fragment_scan.xml
index 948a2d96b9c2d31f5df9066c1a2868a2e8d378fa..af3096c38cf59e773b122b9d2697b39928de04fd 100644
--- a/app/src/main/res/layout/fragment_scan.xml
+++ b/app/src/main/res/layout/fragment_scan.xml
@@ -6,18 +6,27 @@
     android:layout_height="match_parent"
     tools:context=".ui.scan.ScanFragment">
 
-    <TextView
-        android:id="@+id/text_scan"
-        android:layout_width="match_parent"
+
+    <Button
+        android:id="@+id/capture_button"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
-        android:layout_marginTop="8dp"
-        android:layout_marginEnd="8dp"
-        android:textAlignment="center"
-        android:textSize="20sp"
-        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginTop="50dp"
+        android:text="@string/camera_capture_text"
+        app:layout_constraintBottom_toBottomOf="@+id/previewView"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
+    <androidx.camera.view.PreviewView
+        android:id="@+id/previewView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:layout_editor_absoluteX="0dp">
+
+    </androidx.camera.view.PreviewView>
+
+
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/popup_scan_image.xml b/app/src/main/res/layout/popup_scan_image.xml
new file mode 100644
index 0000000000000000000000000000000000000000..62efb8a799d438ef0305d16e556129496d942c09
--- /dev/null
+++ b/app/src/main/res/layout/popup_scan_image.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <Button
+        android:id="@+id/cancel_popup_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Cancel"
+        tools:layout_editor_absoluteX="42dp"
+        tools:layout_editor_absoluteY="621dp" />
+
+    <Button
+        android:id="@+id/save_popup_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="save"
+        tools:layout_editor_absoluteX="198dp"
+        tools:layout_editor_absoluteY="621dp" />
+
+    <TextView
+        android:id="@+id/result_popup_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="hasil"
+        android:textSize="34sp"
+        tools:layout_editor_absoluteX="135dp"
+        tools:layout_editor_absoluteY="358dp" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3f23b7b5412e56016cd394c05fb5f0bd268c83a5..0ac31e5c48ded74d9ad873b5197c6be6c3a27a30 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -15,4 +15,5 @@
     <string name="incorrect_login">Your login credentials are not correct</string>
     <string name="incorrect_email_format">Incorrect email format!</string>
     <string name="keep_me_logged_in">Keep me logged in</string>
+    <string name="camera_capture_text">Capture</string>
 </resources>
\ No newline at end of file