diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e40a96212e0ca27ed185ec5e1d5de957ca615d08..a8cc1ca729631aae8c93f653babb64bb34e2fcdf 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -70,4 +70,11 @@ dependencies {
     // Graph
     implementation("com.github.PhilJay:MPAndroidChart:v3.1.0")
 
+    // Twibbon
+    implementation ("androidx.camera:camera-camera2:1.3.0-alpha03")
+    implementation ("androidx.camera:camera-lifecycle:1.3.0-alpha03")
+    implementation ("androidx.camera:camera-view:1.3.0-alpha03")
+
+
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/atm/bondowowo/ui/twibbon/TwibbonActivity.kt b/app/src/main/java/com/atm/bondowowo/ui/twibbon/TwibbonActivity.kt
index 491996834f03ddbe70d7928b933bd0d1acced234..aa7e26fafd8e9c8a7ddb31c238869a0e9dc497f8 100644
--- a/app/src/main/java/com/atm/bondowowo/ui/twibbon/TwibbonActivity.kt
+++ b/app/src/main/java/com/atm/bondowowo/ui/twibbon/TwibbonActivity.kt
@@ -3,13 +3,133 @@ package com.atm.bondowowo.ui.twibbon
 import android.os.Bundle
 import androidx.appcompat.app.AppCompatActivity
 import com.atm.bondowowo.databinding.ActivityTwibbonBinding
+import android.Manifest
+import android.content.Context
+import android.content.pm.PackageManager
+import android.util.Log
+import android.view.View
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.TextView
+import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.camera.core.CameraSelector
+import androidx.camera.core.Preview
+import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.camera.view.PreviewView
+import androidx.core.content.ContextCompat
+import com.atm.bondowowo.R
+import com.google.common.util.concurrent.ListenableFuture
+
 
 class TwibbonActivity : AppCompatActivity() {
 
     private lateinit var binding: ActivityTwibbonBinding
+
+    private lateinit var mContext: Context
+
+    private lateinit var previewView: PreviewView
+    private lateinit var previewImage: ImageView
+    private lateinit var twibbon: ImageView
+    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
+    private lateinit var warningText: TextView
+    private lateinit var capturePhotoButton: Button
+    private var imagePreview: Boolean = false
+
+    private val requestPermissionLauncher =
+        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
+            if (isGranted) {
+                warningText.visibility = View.GONE
+                capturePhotoButton.visibility = View.VISIBLE
+                previewView.visibility = View.VISIBLE
+                twibbon.visibility = View.VISIBLE
+                Log.d("Twibbon", "berhasil granted")
+            } else {
+                warningText.visibility = View.VISIBLE
+                warningText.text = resources.getString(R.string.twibbon_warning_no_permissions)
+                capturePhotoButton.visibility = View.GONE
+                previewView.visibility = View.GONE
+                twibbon.visibility = View.GONE
+                // Request permission again
+                requestCameraPermission()
+                Log.e("Twibbon", "GAGAL GRANTED")
+            }
+        }
+
+    private fun requestCameraPermission() {
+        requestPermissionLauncher.launch(Manifest.permission.CAMERA)
+    }
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         binding = ActivityTwibbonBinding.inflate(layoutInflater)
         setContentView(binding.root)
+
+        mContext = this
+        cameraProviderFuture = ProcessCameraProvider.getInstance(mContext)
+
+        previewView = findViewById(R.id.previewView)
+        previewView.implementationMode = PreviewView.ImplementationMode.PERFORMANCE
+        previewView.scaleType = PreviewView.ScaleType.FILL_CENTER
+        previewView.visibility = View.VISIBLE
+
+        previewImage = findViewById(R.id.imagePreview)
+        twibbon = findViewById(R.id.twibbon)
+        twibbon.visibility = View.VISIBLE
+
+        warningText = findViewById(R.id.warningCameraTwibbon)
+        warningText.visibility = View.GONE
+
+        capturePhotoButton = findViewById(R.id.btnCapture)
+        capturePhotoButton.visibility = View.VISIBLE
+
+        capturePhotoButton.setOnClickListener {
+            if (imagePreview) {
+                previewView.visibility = View.VISIBLE
+                previewImage.visibility = View.GONE
+                capturePhotoButton.text = resources.getString(R.string.btn_capture)
+                imagePreview = false
+            } else {
+                previewView.visibility = View.GONE
+                previewImage.visibility = View.VISIBLE
+                capturePhotoButton.text = resources.getString(R.string.btn_take_photo)
+                imagePreview = true
+                val bitmap = previewView.bitmap
+                previewImage.setImageBitmap(bitmap)
+                Toast.makeText(mContext, "Image captured", Toast.LENGTH_SHORT).show()
+            }
+        }
+    }
+
+    override fun onStart() {
+        super.onStart()
+        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
+            requestCameraPermission()
+        } else {
+            cameraProviderFuture.addListener({
+                val cameraProvider = cameraProviderFuture.get()
+                bindPreview(cameraProvider)
+            }, ContextCompat.getMainExecutor(mContext))
+        }
+    }
+
+
+    override fun onDestroy() {
+        super.onDestroy()
+        cameraProviderFuture.get().unbindAll()
     }
+
+    private fun bindPreview(cameraProvider: ProcessCameraProvider) {
+        val preview: Preview = Preview.Builder()
+            .build()
+
+        val cameraSelector: CameraSelector = CameraSelector.Builder()
+            .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
+            .build()
+
+        preview.setSurfaceProvider(previewView.surfaceProvider)
+
+        cameraProvider.bindToLifecycle(this, cameraSelector, preview)
+    }
+
 }
\ No newline at end of file
diff --git a/app/src/main/res/drawable/twibbon.png b/app/src/main/res/drawable/twibbon.png
new file mode 100644
index 0000000000000000000000000000000000000000..68ba01d761d477e1e0a0a060e941e9af939234d9
Binary files /dev/null and b/app/src/main/res/drawable/twibbon.png differ
diff --git a/app/src/main/res/layout/activity_twibbon.xml b/app/src/main/res/layout/activity_twibbon.xml
index 7f340509eba3d6a65692f904e10a6a85d05751e6..8abba426432b5d2b2bb1e623a2ec4e8d33b7603b 100644
--- a/app/src/main/res/layout/activity_twibbon.xml
+++ b/app/src/main/res/layout/activity_twibbon.xml
@@ -24,39 +24,78 @@
             android:textStyle="bold" />
     </com.google.android.material.appbar.AppBarLayout>
 
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginTop="40dp"
-        android:orientation="vertical"
-        tools:contex="com.atm.bondowowo.ui.scan.ScanFragment">
+    <androidx.camera.view.PreviewView
+        android:id="@+id/previewView"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintDimensionRatio="1:1"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.35"
+        app:layout_constraintHorizontal_bias="0.5" />
+
+    <ImageView
+        android:visibility="gone"
+        android:id="@+id/imagePreview"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintDimensionRatio="1:1"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.35"
+        app:layout_constraintHorizontal_bias="0.5"
+        android:contentDescription="Image Preview" />
 
-        <com.budiyev.android.codescanner.CodeScannerView
-            android:id="@+id/scanner"
-            android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            app:autoFocusButtonVisible="true" />
+    <ImageView
+        android:id="@+id/twibbon"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:contentDescription="Twibbon"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintDimensionRatio="1:1"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.35"
+        app:srcCompat="@drawable/twibbon"
+        tools:srcCompat="@drawable/twibbon" />
 
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.89">
 
         <Button
-            android:id="@+id/btn_upload"
+            android:id="@+id/btnCapture"
             android:layout_width="wrap_content"
+            android:text="Cekrek"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="Cekrek" />
-
-        <TextView
-            android:id="@+id/tv_result"
-            android:layout_width="match_parent"
-            android:layout_height="40dp"
-            android:layout_marginTop="1dp"
-            android:text="..."
-            android:textAlignment="center"
-            android:textColor="#A92B"
-            android:textSize="20sp" />
+            app:backgroundTint="#012B39"
+            android:textColor="#FFFFFF"
+            app:layout_constraintTop_toTopOf="@+id/textureViewTwibbon"/>
 
     </LinearLayout>
 
+    <TextView
+        android:id="@+id/warningCameraTwibbon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text=""
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.5" />
+
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 955d36d4a1dd24af1ad955727c7b75fa294f5501..ef3075b3031276096feda9a86b06bfde612240b9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -10,6 +10,9 @@
     <string name="upload_file">Upload File</string>
     <string name="use_filter">Use Filter</string>
     <string name="twibbon">Twibbon</string>
+    <string name="twibbon_warning_no_permissions">Camera permission is required to use this feature</string>
+    <string name="btn_capture">Capture</string>
+    <string name="btn_take_photo">Take Again</string>
     <string-array name="transaction_option">
         <item>Edit</item>
         <item>Delete</item>