feat: Add support for creating events
This commit is contained in:
parent
82f300fdd9
commit
3df1faa17c
|
@ -16,6 +16,9 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.NeatCalendar"
|
android:theme="@style/Theme.NeatCalendar"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".activities.CreateEventActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.DayViewActivity"
|
android:name=".activities.DayViewActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
package com.p_vacho.neat_calendar.activities
|
||||||
|
|
||||||
|
import android.app.DatePickerDialog
|
||||||
|
import android.app.TimePickerDialog
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
|
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
|
import com.p_vacho.neat_calendar.R
|
||||||
|
import com.p_vacho.neat_calendar.api.RetrofitClient
|
||||||
|
import com.p_vacho.neat_calendar.api.models.EventRequest
|
||||||
|
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import retrofit2.HttpException
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
|
||||||
|
class CreateEventActivity : AppCompatActivity() {
|
||||||
|
private lateinit var etEventTitle: EditText
|
||||||
|
private lateinit var etEventDescription: EditText
|
||||||
|
private lateinit var eventTypeToggleGroup: MaterialButtonToggleGroup
|
||||||
|
private lateinit var btnInstantEvent: MaterialButton
|
||||||
|
private lateinit var btnDurationEvent: MaterialButton
|
||||||
|
private lateinit var txtStartTime: TextInputEditText
|
||||||
|
private lateinit var txtEndTime: TextInputEditText
|
||||||
|
private lateinit var btnCreateEvent: MaterialButton
|
||||||
|
|
||||||
|
private lateinit var defaultDate: LocalDate
|
||||||
|
|
||||||
|
private var instantEvent: Boolean = true
|
||||||
|
private var startDateTime: LocalDateTime? = null
|
||||||
|
private var endDateTime: LocalDateTime? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_create_event)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The getParcelableExtra wants the class as a second argument to
|
||||||
|
// be more type-safe, but this is only supported since api 33, which is over
|
||||||
|
// our min api version, so we can ignore this deprecation for now.
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val dateString = intent.getStringExtra("date")!!
|
||||||
|
defaultDate = LocalDate.parse(dateString)
|
||||||
|
|
||||||
|
initializeViews()
|
||||||
|
setupListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeViews() {
|
||||||
|
etEventTitle = findViewById(R.id.etEventTitle)
|
||||||
|
etEventDescription = findViewById(R.id.etEventDescription)
|
||||||
|
eventTypeToggleGroup = findViewById(R.id.eventTypeToggleGroup)
|
||||||
|
btnInstantEvent = findViewById(R.id.btnInstantEvent)
|
||||||
|
btnDurationEvent = findViewById(R.id.btnDurationEvent)
|
||||||
|
txtStartTime = findViewById(R.id.txtStartTime)
|
||||||
|
txtEndTime = findViewById(R.id.txtEndTime)
|
||||||
|
btnCreateEvent = findViewById(R.id.btnCreateEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListeners() {
|
||||||
|
eventTypeToggleGroup.addOnButtonCheckedListener { group, checkedId, isChecked ->
|
||||||
|
if (isChecked) { // Triggered only for the newly selected button
|
||||||
|
when (checkedId) {
|
||||||
|
R.id.btnInstantEvent -> {
|
||||||
|
txtEndTime.visibility = View.GONE
|
||||||
|
txtEndTime.setText("")
|
||||||
|
endDateTime = null
|
||||||
|
instantEvent = true
|
||||||
|
}
|
||||||
|
R.id.btnDurationEvent -> {
|
||||||
|
txtEndTime.visibility = View.VISIBLE
|
||||||
|
instantEvent = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
txtStartTime.setOnClickListener {
|
||||||
|
val defaultDateTime = startDateTime ?: defaultDate.atTime(12, 0)
|
||||||
|
showDateTimePicker(defaultDateTime) { selectedDateTime ->
|
||||||
|
startDateTime = selectedDateTime
|
||||||
|
txtStartTime.setText(formatDateTime(selectedDateTime))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
txtEndTime.setOnClickListener {
|
||||||
|
val defaultDateTime = endDateTime ?: startDateTime ?: defaultDate.atTime(12, 0)
|
||||||
|
showDateTimePicker(defaultDateTime) { selectedDateTime ->
|
||||||
|
if (!selectedDateTime.isAfter(startDateTime)) {
|
||||||
|
Toast.makeText(this, "End time must be after start time", Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
endDateTime = selectedDateTime
|
||||||
|
txtEndTime.setText(formatDateTime(selectedDateTime))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btnCreateEvent.setOnClickListener { createEvent() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createEvent() {
|
||||||
|
val title = etEventTitle.text.toString()
|
||||||
|
val description = etEventDescription.text.toString()
|
||||||
|
|
||||||
|
if (title.isEmpty() || startDateTime == null) {
|
||||||
|
Toast.makeText(this, "Please provide a title and start time", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!instantEvent && endDateTime == null) {
|
||||||
|
Toast.makeText(this, "Please provide an end time or use an instant event", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val eventRequest = EventRequest(
|
||||||
|
title = title,
|
||||||
|
description = description,
|
||||||
|
category_ids = emptyList(), // Categories will be added later
|
||||||
|
start_time = startDateTime!!.atZone(ZoneId.systemDefault()).toOffsetDateTime(),
|
||||||
|
end_time = endDateTime?.atZone(ZoneId.systemDefault())?.toOffsetDateTime()
|
||||||
|
?: startDateTime!!.atZone(ZoneId.systemDefault()).toOffsetDateTime(),
|
||||||
|
color = Color.valueOf(0xFF33AABB.toInt()) // Placeholder color
|
||||||
|
)
|
||||||
|
|
||||||
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
val createdEvent = RetrofitClient.eventsService.createEvent(eventRequest)
|
||||||
|
withContext(Dispatchers.Main) { handleEventCreated(createdEvent) }
|
||||||
|
} catch (e: HttpException) {
|
||||||
|
if (e.code() != 400) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast.makeText(
|
||||||
|
this@CreateEventActivity,
|
||||||
|
"Failed to create event",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleEventCreated(createdEvent: EventResponse) {
|
||||||
|
Toast.makeText(this, "Event Created: ${createdEvent.title}", Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
|
val intent = Intent().apply {
|
||||||
|
putExtra("newEvent", createdEvent)
|
||||||
|
}
|
||||||
|
setResult(RESULT_OK, intent) // Pass the event back
|
||||||
|
|
||||||
|
finish() // Close the activity and return
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showDateTimePicker(
|
||||||
|
initialDateTime: LocalDateTime?,
|
||||||
|
onDateTimeSelected: (LocalDateTime) -> Unit
|
||||||
|
) {
|
||||||
|
val now = initialDateTime ?: LocalDateTime.now()
|
||||||
|
|
||||||
|
val datePicker = DatePickerDialog(this, { _, year, month, dayOfMonth ->
|
||||||
|
val timePicker = TimePickerDialog(this, { _, hourOfDay, minute ->
|
||||||
|
val selectedDateTime = LocalDateTime.of(year, month + 1, dayOfMonth, hourOfDay, minute)
|
||||||
|
onDateTimeSelected(selectedDateTime)
|
||||||
|
}, now.hour, now.minute, true)
|
||||||
|
timePicker.show()
|
||||||
|
}, now.year, now.monthValue - 1, now.dayOfMonth)
|
||||||
|
datePicker.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatDateTime(dateTime: LocalDateTime?): String {
|
||||||
|
return dateTime?.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) ?: "Select Time"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package com.p_vacho.neat_calendar.activities
|
package com.p_vacho.neat_calendar.activities
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
@ -11,6 +13,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.p_vacho.neat_calendar.R
|
import com.p_vacho.neat_calendar.R
|
||||||
import com.p_vacho.neat_calendar.adapters.EventCardAdapter
|
import com.p_vacho.neat_calendar.adapters.EventCardAdapter
|
||||||
|
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||||
import com.p_vacho.neat_calendar.models.CalendarDay
|
import com.p_vacho.neat_calendar.models.CalendarDay
|
||||||
|
|
||||||
class DayViewActivity : AppCompatActivity() {
|
class DayViewActivity : AppCompatActivity() {
|
||||||
|
@ -19,6 +22,20 @@ class DayViewActivity : AppCompatActivity() {
|
||||||
private lateinit var tvDate: TextView
|
private lateinit var tvDate: TextView
|
||||||
private lateinit var rvEvents: RecyclerView
|
private lateinit var rvEvents: RecyclerView
|
||||||
|
|
||||||
|
private lateinit var calendarDay: CalendarDay
|
||||||
|
private lateinit var events: MutableList<EventResponse>
|
||||||
|
|
||||||
|
private val createEventLauncher = registerForActivityResult(
|
||||||
|
androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result ->
|
||||||
|
if (result.resultCode == RESULT_OK) {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val newEvent: EventResponse? = result.data?.getParcelableExtra("newEvent")
|
||||||
|
|
||||||
|
newEvent?.let { addNewEvent(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
|
@ -33,32 +50,39 @@ class DayViewActivity : AppCompatActivity() {
|
||||||
// be more type-safe, but this is only supported since api 33, which is over
|
// be more type-safe, but this is only supported since api 33, which is over
|
||||||
// our min api version, so we can ignore this deprecation for now.
|
// our min api version, so we can ignore this deprecation for now.
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
val calendarDay = intent.getParcelableExtra<CalendarDay>("calendarDay")!!
|
calendarDay = intent.getParcelableExtra("calendarDay")!!
|
||||||
|
|
||||||
// It's possible that events will be removed by the event card adapter, use a
|
events = calendarDay.events.sortedBy { it.start_time }.toMutableList()
|
||||||
// mutable list to keep track of them from here. We don't currently propagate
|
|
||||||
// these changes anywhere, going back to calendar activity will just trigger
|
|
||||||
// an api refetch, which is sufficient for now, but in the future, we could.
|
|
||||||
val events = calendarDay.events.toMutableList()
|
|
||||||
|
|
||||||
// Setup the UI
|
// Initialize Views
|
||||||
tvDate = findViewById(R.id.tvDate)
|
tvDate = findViewById(R.id.tvDate)
|
||||||
rvEvents = findViewById(R.id.rvEvents)
|
rvEvents = findViewById(R.id.rvEvents)
|
||||||
btnBack = findViewById(R.id.btnBack)
|
btnBack = findViewById(R.id.btnBack)
|
||||||
btnAddEvent = findViewById(R.id.btnAddEvent)
|
btnAddEvent = findViewById(R.id.btnAddEvent)
|
||||||
|
|
||||||
btnBack.setOnClickListener {
|
// Setup UI
|
||||||
// Handle back navigation
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
btnAddEvent.setOnClickListener {
|
|
||||||
TODO("Implement adding events")
|
|
||||||
}
|
|
||||||
|
|
||||||
tvDate.text = calendarDay.date.toString()
|
tvDate.text = calendarDay.date.toString()
|
||||||
|
|
||||||
rvEvents.layoutManager = LinearLayoutManager(this)
|
rvEvents.layoutManager = LinearLayoutManager(this)
|
||||||
rvEvents.adapter = EventCardAdapter(events, this)
|
rvEvents.adapter = EventCardAdapter(events, this)
|
||||||
|
|
||||||
|
btnBack.setOnClickListener { finish() }
|
||||||
|
btnAddEvent.setOnClickListener { navigateToCreateEventActivity() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun navigateToCreateEventActivity() {
|
||||||
|
val intent = Intent(this, CreateEventActivity::class.java).apply {
|
||||||
|
putExtra("date", calendarDay.date.toString())
|
||||||
|
}
|
||||||
|
createEventLauncher.launch(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addNewEvent(newEvent: EventResponse) {
|
||||||
|
events.add(newEvent)
|
||||||
|
events.sortBy { it.start_time }
|
||||||
|
|
||||||
|
// We can't be more specific, we don't know the id due to sorting
|
||||||
|
@Suppress("NotifyDataSetChanged")
|
||||||
|
rvEvents.adapter!!.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,4 +20,13 @@ data class EventResponse(
|
||||||
val owner_user_id: String,
|
val owner_user_id: String,
|
||||||
val attendee_ids: List<String>,
|
val attendee_ids: List<String>,
|
||||||
val created_at: OffsetDateTime
|
val created_at: OffsetDateTime
|
||||||
): Parcelable
|
): Parcelable
|
||||||
|
|
||||||
|
data class EventRequest(
|
||||||
|
val title: String,
|
||||||
|
val description: String,
|
||||||
|
val category_ids: List<String>,
|
||||||
|
val start_time: OffsetDateTime,
|
||||||
|
val end_time: OffsetDateTime,
|
||||||
|
val color: Color,
|
||||||
|
)
|
|
@ -1,8 +1,11 @@
|
||||||
package com.p_vacho.neat_calendar.api.services
|
package com.p_vacho.neat_calendar.api.services
|
||||||
|
|
||||||
|
import com.p_vacho.neat_calendar.api.models.EventRequest
|
||||||
import com.p_vacho.neat_calendar.api.models.EventResponse
|
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||||
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.DELETE
|
import retrofit2.http.DELETE
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.POST
|
||||||
import retrofit2.http.Path
|
import retrofit2.http.Path
|
||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
|
@ -31,4 +34,7 @@ interface EventsService {
|
||||||
|
|
||||||
@DELETE("events/{event_id}")
|
@DELETE("events/{event_id}")
|
||||||
suspend fun deleteEvent(@Path("event_id") eventId: String): Unit
|
suspend fun deleteEvent(@Path("event_id") eventId: String): Unit
|
||||||
|
|
||||||
|
@POST("events")
|
||||||
|
suspend fun createEvent(@Body eventData: EventRequest): EventResponse
|
||||||
}
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?attr/colorPrimary" android:state_checked="true" />
|
||||||
|
<item android:color="?attr/colorSecondary" />
|
||||||
|
</selector>
|
5
app/src/main/res/color/toggle_button_stroke_selector.xml
Normal file
5
app/src/main/res/color/toggle_button_stroke_selector.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?attr/colorOnPrimary" android:state_checked="true" />
|
||||||
|
<item android:color="?attr/colorOnSecondary" />
|
||||||
|
</selector>
|
140
app/src/main/res/layout/activity_create_event.xml
Normal file
140
app/src/main/res/layout/activity_create_event.xml
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:padding="16dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="4dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_margin="15dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<!-- Event Title -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/event_title"
|
||||||
|
app:boxStrokeWidth="1dp"
|
||||||
|
app:boxStrokeColor="?attr/colorPrimary">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etEventTitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<!-- Event Description -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:hint="@string/event_description"
|
||||||
|
app:boxStrokeWidth="1dp"
|
||||||
|
app:boxStrokeColor="?attr/colorPrimary">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etEventDescription"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
android:maxLines="3"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<!-- Event Type Toggle -->
|
||||||
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
android:id="@+id/eventTypeToggleGroup"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
app:singleSelection="true"
|
||||||
|
app:checkedButton="@id/btnInstantEvent">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnInstantEvent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/instant_event"
|
||||||
|
android:checkable="true"
|
||||||
|
app:backgroundTint="@color/toggle_button_background_selector"
|
||||||
|
app:strokeColor="@color/toggle_button_stroke_selector"
|
||||||
|
app:strokeWidth="2dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnDurationEvent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/duration_event"
|
||||||
|
android:checkable="true"
|
||||||
|
app:backgroundTint="@color/toggle_button_background_selector"
|
||||||
|
app:strokeColor="@color/toggle_button_stroke_selector"
|
||||||
|
app:strokeWidth="2dp" />
|
||||||
|
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||||
|
|
||||||
|
<!-- Start Time -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:hint="@string/start_time"
|
||||||
|
app:boxStrokeWidth="1dp"
|
||||||
|
app:boxStrokeColor="?attr/colorPrimary">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/txtStartTime"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="false"
|
||||||
|
android:clickable="true" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<!-- End Time -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:hint="@string/end_time"
|
||||||
|
app:boxStrokeWidth="1dp"
|
||||||
|
app:boxStrokeColor="?attr/colorPrimary">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/txtEndTime"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="false"
|
||||||
|
android:clickable="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<!-- Create Button -->
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnCreateEvent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="@string/create_event"
|
||||||
|
app:cornerRadius="8dp" />
|
||||||
|
|
||||||
|
<!-- Close Button -->
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnClose"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/close"
|
||||||
|
app:icon="@drawable/ic_arrow_back"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconPadding="8dp"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton" />
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
|
@ -33,4 +33,11 @@
|
||||||
<string name="edit_event">Edit this event</string>
|
<string name="edit_event">Edit this event</string>
|
||||||
<string name="add_event">Add a new event</string>
|
<string name="add_event">Add a new event</string>
|
||||||
<string name="back">Go to the previous page</string>
|
<string name="back">Go to the previous page</string>
|
||||||
|
<string name="event_title">Event Title</string>
|
||||||
|
<string name="event_description">Event Description</string>
|
||||||
|
<string name="instant_event">Instant Event</string>
|
||||||
|
<string name="duration_event">Duration Event</string>
|
||||||
|
<string name="start_time">Start Time</string>
|
||||||
|
<string name="end_time">End Time</string>
|
||||||
|
<string name="create_event">Create Event</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue