added fixed coachcode after login.

This commit is contained in:
oxidiert
2025-09-29 11:59:51 +02:00
parent cfcb689ffc
commit 851676f6c3
7 changed files with 134 additions and 80 deletions

View File

@ -4,10 +4,10 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-09-21T10:53:27.572746300Z"> <DropdownSelection timestamp="2025-09-29T09:46:59.707167200Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\danie\.android\avd\Medium_Phone.avd" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=HA218GZY" />
</handle> </handle>
</Target> </Target>
</DropdownSelection> </DropdownSelection>

2
.idea/misc.xml generated
View File

@ -10,7 +10,7 @@
<component name="VisualizationToolProject"> <component name="VisualizationToolProject">
<option name="state"> <option name="state">
<ProjectState> <ProjectState>
<option name="scale" value="0.32218749999999996" /> <option name="scale" value="0.1221923828125" />
</ProjectState> </ProjectState>
</option> </option>
</component> </component>

6
.idea/render.experimental.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RenderSettings">
<option name="showDecorations" value="true" />
</component>
</project>

View File

@ -20,6 +20,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
private var languageID: String = "GERMAN" private var languageID: String = "GERMAN"
private lateinit var editText: EditText private lateinit var editText: EditText
private lateinit var coachEditText: EditText
private lateinit var spinner: Spinner private lateinit var spinner: Spinner
private lateinit var textView: TextView private lateinit var textView: TextView
private lateinit var buttonContainer: LinearLayout private lateinit var buttonContainer: LinearLayout
@ -29,8 +30,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
private lateinit var uploadButton: Button private lateinit var uploadButton: Button
private lateinit var downloadButton: Button private lateinit var downloadButton: Button
private lateinit var databaseButton: Button private lateinit var databaseButton: Button
// NEU: Status-Leiste
private lateinit var statusSession: TextView private lateinit var statusSession: TextView
private lateinit var statusOnline: TextView private lateinit var statusOnline: TextView
@ -49,18 +48,16 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
private var uiFreeze: Boolean = false private var uiFreeze: Boolean = false
// Status-Updater (jede Minute)
private val uiHandler = Handler(Looper.getMainLooper()) private val uiHandler = Handler(Looper.getMainLooper())
private val statusTicker = object : Runnable { private val statusTicker = object : Runnable {
override fun run() { override fun run() {
updateStatusStrip() updateStatusStrip()
uiHandler.postDelayed(this, 60_000) // jede Minute uiHandler.postDelayed(this, 60_000)
} }
} }
// Feste Standard-Randfarben private val STROKE_ENABLED = Color.parseColor("#8C79F2")
private val STROKE_ENABLED = Color.parseColor("#8C79F2") // wenn anklickbar private val STROKE_DISABLED = Color.parseColor("#D8D3F5")
private val STROKE_DISABLED = Color.parseColor("#D8D3F5") // wenn nicht anklickbar
private fun t(id: String) = LanguageManager.getText(languageID, id) private fun t(id: String) = LanguageManager.getText(languageID, id)
@ -70,6 +67,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
loadQuestionnaireOrder() loadQuestionnaireOrder()
createQuestionnaireButtons() createQuestionnaireButtons()
restorePreviousClientCode() restorePreviousClientCode()
lockCoachCodeField()
setupLanguageSpinner() setupLanguageSpinner()
setupLoadButton() setupLoadButton()
setupSaveButton() setupSaveButton()
@ -77,12 +75,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
setupUploadButton() setupUploadButton()
setupDownloadButton() setupDownloadButton()
setupDatabaseButtonHandler() setupDatabaseButtonHandler()
// Statusleiste initial & Ticker starten
uiHandler.removeCallbacks(statusTicker) uiHandler.removeCallbacks(statusTicker)
updateStatusStrip() updateStatusStrip()
uiHandler.post(statusTicker) uiHandler.post(statusTicker)
val pathExists = File("/data/data/com.dano.test1/databases/questionnaire_database").exists() val pathExists = File("/data/data/com.dano.test1/databases/questionnaire_database").exists()
updateMainButtonsState(pathExists) updateMainButtonsState(pathExists)
if (pathExists && !editText.text.isNullOrBlank()) buttonLoad.performClick() if (pathExists && !editText.text.isNullOrBlank()) buttonLoad.performClick()
@ -90,6 +85,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
private fun bindViews() { private fun bindViews() {
editText = activity.findViewById(R.id.editText) editText = activity.findViewById(R.id.editText)
coachEditText = activity.findViewById(R.id.coachEditText)
spinner = activity.findViewById(R.id.string_spinner1) spinner = activity.findViewById(R.id.string_spinner1)
textView = activity.findViewById(R.id.textView) textView = activity.findViewById(R.id.textView)
buttonContainer = activity.findViewById(R.id.buttonContainer) buttonContainer = activity.findViewById(R.id.buttonContainer)
@ -99,13 +95,12 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
uploadButton = activity.findViewById(R.id.uploadButton) uploadButton = activity.findViewById(R.id.uploadButton)
downloadButton = activity.findViewById(R.id.downloadButton) downloadButton = activity.findViewById(R.id.downloadButton)
databaseButton = activity.findViewById(R.id.databaseButton) databaseButton = activity.findViewById(R.id.databaseButton)
// NEU:
statusSession = activity.findViewById(R.id.statusSession) statusSession = activity.findViewById(R.id.statusSession)
statusOnline = activity.findViewById(R.id.statusOnline) statusOnline = activity.findViewById(R.id.statusOnline)
val tag = editText.tag as? String ?: "" val tag = editText.tag as? String ?: ""
editText.hint = t(tag) editText.hint = t(tag)
val coachTag = coachEditText.tag as? String ?: ""
coachEditText.hint = t(coachTag)
textView.text = t("example_text") textView.text = t("example_text")
} }
@ -114,7 +109,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
val inputStream = activity.assets.open("questionnaire_order.json") val inputStream = activity.assets.open("questionnaire_order.json")
val json = inputStream.bufferedReader().use { it.readText() } val json = inputStream.bufferedReader().use { it.readText() }
val jsonArray = JSONArray(json) val jsonArray = JSONArray(json)
questionnaireEntries = (0 until jsonArray.length()).map { i -> questionnaireEntries = (0 until jsonArray.length()).map { i ->
val obj = jsonArray.getJSONObject(i) val obj = jsonArray.getJSONObject(i)
val file = obj.getString("file") val file = obj.getString("file")
@ -173,10 +167,8 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
dynamicButtons.clear() dynamicButtons.clear()
questionnaireFiles.clear() questionnaireFiles.clear()
cardParts.clear() cardParts.clear()
val vMargin = dp(8) val vMargin = dp(8)
val startEnabled = mutableListOf<Button>() val startEnabled = mutableListOf<Button>()
questionnaireEntries.forEachIndexed { index, entry -> questionnaireEntries.forEachIndexed { index, entry ->
val row = FrameLayout(activity).apply { val row = FrameLayout(activity).apply {
layoutParams = LinearLayout.LayoutParams( layoutParams = LinearLayout.LayoutParams(
@ -184,7 +176,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
LinearLayout.LayoutParams.WRAP_CONTENT LinearLayout.LayoutParams.WRAP_CONTENT
).also { it.setMargins(0, vMargin, 0, vMargin) } ).also { it.setMargins(0, vMargin, 0, vMargin) }
} }
val btn = MaterialButton(activity).apply { val btn = MaterialButton(activity).apply {
layoutParams = FrameLayout.LayoutParams( layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT,
@ -210,7 +201,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
applySetButtonsEnabled(dynamicButtons.filter { it == this }, allowCompleted = false, force = false) applySetButtonsEnabled(dynamicButtons.filter { it == this }, allowCompleted = false, force = false)
} }
} }
val textColumn = LinearLayout(activity).apply { val textColumn = LinearLayout(activity).apply {
orientation = LinearLayout.VERTICAL orientation = LinearLayout.VERTICAL
layoutParams = FrameLayout.LayoutParams( layoutParams = FrameLayout.LayoutParams(
@ -231,7 +221,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
} }
textColumn.addView(tvTitle) textColumn.addView(tvTitle)
textColumn.addView(tvSubtitle) textColumn.addView(tvSubtitle)
val chip = TextView(activity).apply { val chip = TextView(activity).apply {
setPadding(dp(14), dp(8), dp(14), dp(8)) setPadding(dp(14), dp(8), dp(14), dp(8))
setTextColor(Color.WHITE) setTextColor(Color.WHITE)
@ -244,29 +233,34 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
Gravity.END or Gravity.CENTER_VERTICAL Gravity.END or Gravity.CENTER_VERTICAL
).also { it.marginEnd = dp(16) } ).also { it.marginEnd = dp(16) }
} }
row.addView(btn) row.addView(btn)
row.addView(textColumn) row.addView(textColumn)
row.addView(chip) row.addView(chip)
buttonContainer.addView(row) buttonContainer.addView(row)
dynamicButtons.add(btn) dynamicButtons.add(btn)
questionnaireFiles[btn] = entry.file questionnaireFiles[btn] = entry.file
cardParts[btn] = CardParts(tvTitle, tvSubtitle, chip) cardParts[btn] = CardParts(tvTitle, tvSubtitle, chip)
tvTitle.text = "Questionnaire ${index + 1}" tvTitle.text = "Questionnaire ${index + 1}"
if (entry.condition is QuestionItem.Condition.AlwaysAvailable) startEnabled.add(btn) if (entry.condition is QuestionItem.Condition.AlwaysAvailable) startEnabled.add(btn)
} }
applyUpdateButtonTexts(force = false) applyUpdateButtonTexts(force = false)
applySetButtonsEnabled(startEnabled, allowCompleted = false, force = false) applySetButtonsEnabled(startEnabled, allowCompleted = false, force = false)
} }
private fun restorePreviousClientCode() { private fun restorePreviousClientCode() {
GlobalValues.LAST_CLIENT_CODE?.let { editText.setText(it) } val username = TokenStore.getUsername(activity)
if (!username.isNullOrBlank()) {
coachEditText.setText(username)
lockCoachCodeField()
return
}
GlobalValues.LAST_CLIENT_CODE?.let {
editText.setText(it)
GlobalValues.LOADED_CLIENT_CODE = it
}
} }
private fun setupLanguageSpinner() { private fun setupLanguageSpinner() {
val languages = listOf("GERMAN", "ENGLISH", "FRENCH", "ROMANIAN", "ARABIC", "POLISH", "TURKISH", "UKRAINIAN", "RUSSIAN", "SPANISH") val languages = listOf("GERMAN", "ENGLISH", "FRENCH", "ROMANIAN", "ARABIC", "POLISH", "TURKISH", "UKRAINIAN", "RUSSIAN", "SPANISH")
val adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, languages).apply { val adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, languages).apply {
@ -280,6 +274,8 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
applyUpdateButtonTexts(force = false) applyUpdateButtonTexts(force = false)
val hintTag = editText.tag as? String ?: "" val hintTag = editText.tag as? String ?: ""
editText.hint = t(hintTag) editText.hint = t(hintTag)
val coachTag = coachEditText.tag as? String ?: ""
coachEditText.hint = t(coachTag)
} }
override fun onNothingSelected(parent: AdapterView<*>) {} override fun onNothingSelected(parent: AdapterView<*>) {}
} }
@ -302,25 +298,18 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
private fun applyUpdateButtonTexts(force: Boolean) { private fun applyUpdateButtonTexts(force: Boolean) {
if (uiFreeze && !force) return if (uiFreeze && !force) return
// Statuszeile bei jedem Refresh aktualisieren
updateStatusStrip() updateStatusStrip()
questionnaireFiles.forEach { (button, fileName) -> questionnaireFiles.forEach { (button, fileName) ->
val entry = questionnaireEntries.firstOrNull { it.file == fileName } val entry = questionnaireEntries.firstOrNull { it.file == fileName }
val key = fileName.substringAfter("questionnaire_").substringAfter("_").removeSuffix(".json") val key = fileName.substringAfter("questionnaire_").substringAfter("_").removeSuffix(".json")
val titleText = t(key) val titleText = t(key)
val parts = cardParts[button] ?: return@forEach val parts = cardParts[button] ?: return@forEach
parts.title.text = titleText parts.title.text = titleText
val points = buttonPoints.entries.firstOrNull { fileName.contains(it.key, ignoreCase = true) }?.value val points = buttonPoints.entries.firstOrNull { fileName.contains(it.key, ignoreCase = true) }?.value
val completed = isCompleted(button) val completed = isCompleted(button)
val enabled = button.isEnabled val enabled = button.isEnabled
val locked = !enabled && !completed val locked = !enabled && !completed
setClickableStroke(button, enabled) setClickableStroke(button, enabled)
if (locked) { if (locked) {
setLockedAppearance(button, true) setLockedAppearance(button, true)
parts.title.setTextColor(Color.WHITE) parts.title.setTextColor(Color.WHITE)
@ -331,7 +320,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
parts.subtitle.setTextColor(Color.parseColor("#7B7794")) parts.subtitle.setTextColor(Color.parseColor("#7B7794"))
applyTintForButton(button, points, emphasize = enabled) applyTintForButton(button, points, emphasize = enabled)
} }
if (entry?.showPoints == true && points != null) { if (entry?.showPoints == true && points != null) {
parts.subtitle.visibility = View.VISIBLE parts.subtitle.visibility = View.VISIBLE
parts.subtitle.text = "${t("points")}: $points" parts.subtitle.text = "${t("points")}: $points"
@ -339,7 +327,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
parts.subtitle.visibility = View.GONE parts.subtitle.visibility = View.GONE
parts.subtitle.text = "" parts.subtitle.text = ""
} }
when { when {
completed -> { completed -> {
parts.chip.text = t("done") parts.chip.text = t("done")
@ -358,33 +345,29 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
} }
} }
} }
buttonLoad.text = t("load") buttonLoad.text = t("load")
saveButton.text = t("save") saveButton.text = t("save")
editButton.text = t("edit") editButton.text = t("edit")
uploadButton.text = t("upload") uploadButton.text = t("upload")
downloadButton.text = t("download") downloadButton.text = t("download")
databaseButton.text = t("database") databaseButton.text = t("database")
val hintTag = editText.tag as? String ?: "" val hintTag = editText.tag as? String ?: ""
editText.hint = t(hintTag) editText.hint = t(hintTag)
val coachTag = coachEditText.tag as? String ?: ""
coachEditText.hint = t(coachTag)
textView.text = t("example_text") textView.text = t("example_text")
} }
private fun applySetButtonsEnabled(enabledButtons: List<Button>, allowCompleted: Boolean, force: Boolean) { private fun applySetButtonsEnabled(enabledButtons: List<Button>, allowCompleted: Boolean, force: Boolean) {
if (uiFreeze && !force) return if (uiFreeze && !force) return
questionnaireFiles.keys.forEach { button -> questionnaireFiles.keys.forEach { button ->
val completed = isCompleted(button) val completed = isCompleted(button)
val isAllowed = enabledButtons.contains(button) val isAllowed = enabledButtons.contains(button)
val shouldEnable = if (allowCompleted) isAllowed else isAllowed && !completed val shouldEnable = if (allowCompleted) isAllowed else isAllowed && !completed
val locked = !shouldEnable && !completed val locked = !shouldEnable && !completed
button.isEnabled = shouldEnable button.isEnabled = shouldEnable
button.alpha = if (completed || shouldEnable) 1.0f else 0.6f button.alpha = if (completed || shouldEnable) 1.0f else 0.6f
setClickableStroke(button, shouldEnable) setClickableStroke(button, shouldEnable)
cardParts[button]?.let { parts -> cardParts[button]?.let { parts ->
if (locked) { if (locked) {
setLockedAppearance(button, true) setLockedAppearance(button, true)
@ -396,7 +379,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
parts.subtitle.setTextColor(Color.parseColor("#7B7794")) parts.subtitle.setTextColor(Color.parseColor("#7B7794"))
applyTintForButton(button, getPointsForButton(button), emphasize = shouldEnable) applyTintForButton(button, getPointsForButton(button), emphasize = shouldEnable)
} }
when { when {
completed -> { completed -> {
parts.chip.text = t("done") parts.chip.text = t("done")
@ -522,7 +504,6 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
private fun applyTintForButton(button: Button, points: Int?, emphasize: Boolean) { private fun applyTintForButton(button: Button, points: Int?, emphasize: Boolean) {
val file = questionnaireFiles[button] ?: return val file = questionnaireFiles[button] ?: return
val entry = questionnaireEntries.firstOrNull { it.file == file } val entry = questionnaireEntries.firstOrNull { it.file == file }
if (entry?.showPoints != true) { if (entry?.showPoints != true) {
val mb = button as? MaterialButton ?: return val mb = button as? MaterialButton ?: return
mb.backgroundTintList = ColorStateList.valueOf(if (emphasize) Color.parseColor("#F1EEFF") else Color.WHITE) mb.backgroundTintList = ColorStateList.valueOf(if (emphasize) Color.parseColor("#F1EEFF") else Color.WHITE)
@ -554,23 +535,34 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
mb.strokeColor = ColorStateList.valueOf(if (emphasize) STROKE_ENABLED else STROKE_DISABLED) mb.strokeColor = ColorStateList.valueOf(if (emphasize) STROKE_ENABLED else STROKE_DISABLED)
} }
// === NEU: Status-Logik ===
private fun updateStatusStrip() { private fun updateStatusStrip() {
// Session-Alter
val ts = TokenStore.getLoginTimestamp(activity) val ts = TokenStore.getLoginTimestamp(activity)
val ageMs = if (ts > 0L) (System.currentTimeMillis() - ts) else 0L val ageMs = if (ts > 0L) (System.currentTimeMillis() - ts) else 0L
val h = TimeUnit.MILLISECONDS.toHours(ageMs) val h = TimeUnit.MILLISECONDS.toHours(ageMs)
val m = TimeUnit.MILLISECONDS.toMinutes(ageMs) - h * 60 val m = TimeUnit.MILLISECONDS.toMinutes(ageMs) - h * 60
statusSession.text = if (ts > 0L) "Session: ${h}h ${m}m" else "Session: —" statusSession.text = if (ts > 0L) "Session: ${h}h ${m}m" else "Session: —"
// Online/Offline
val online = NetworkUtils.isOnline(activity) val online = NetworkUtils.isOnline(activity)
statusOnline.text = if (online) "Online" else "Offline" statusOnline.text = if (online) "Online" else "Offline"
statusOnline.setTextColor(if (online) Color.parseColor("#2E7D32") else Color.parseColor("#C62828")) statusOnline.setTextColor(if (online) Color.parseColor("#2E7D32") else Color.parseColor("#C62828"))
} }
fun refreshHeaderStatusLive() { fun refreshHeaderStatusLive() {
// nutzt deine bestehende Update-Logik und erzwingt ein Neuzeichnen
applyUpdateButtonTexts(force = true) applyUpdateButtonTexts(force = true)
} }
private fun lockCoachCodeField() {
coachEditText.isFocusable = false
coachEditText.isFocusableInTouchMode = false
coachEditText.isCursorVisible = false
coachEditText.keyListener = null
coachEditText.isLongClickable = false
coachEditText.isClickable = false
coachEditText.setBackgroundResource(R.drawable.bg_field_locked)
coachEditText.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_24, 0)
coachEditText.compoundDrawablePadding = dp(8)
coachEditText.alpha = 0.95f
}
} }

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#F4F4F6"/>
<stroke android:width="1dp" android:color="#C7C7D0"/>
<corners android:radius="8dp"/>
<padding android:left="12dp" android:top="12dp" android:right="12dp" android:bottom="12dp"/>
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportHeight="24">
<path
android:fillColor="#8C79F2"
android:pathData="M12,17a2,2 0,1 0,0 -4 2,2 0,0 0,0 4zM18,8h-1V6a5,5 0,0 0,-10 0v2H6a2,2 0,0 0,-2 2v8a2,2 0,0 0,2 2h12a2,2 0,0 0,2 -2v-8a2,2 0,0 0,-2 -2zM8,6a4,4 0,0 1,8 0v2H8z"/>
</vector>

View File

@ -23,13 +23,39 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"> app:layout_constraintEnd_toEndOf="parent">
<!-- Neu: vertikale Anordnung -> Eingaben + Statuszeile -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<!-- Zeile mit Sprache + Client-Code --> <!-- Language (eigene Zeile) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="6dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="12dp"
android:paddingBottom="6dp"
android:text="Language"
android:textColor="@color/brand_text_dark"
android:textSize="12sp" />
<Spinner
android:id="@+id/string_spinner1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_field_filled"
android:paddingStart="12dp"
android:paddingEnd="12dp" />
</LinearLayout>
<!-- Client Code | Coach Code (gemeinsame Zeile) -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -48,34 +74,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Language"
android:textColor="@color/brand_text_dark"
android:textSize="12sp"
android:paddingStart="4dp"
android:paddingBottom="6dp"/>
<Spinner
android:id="@+id/string_spinner1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_field_filled"
android:paddingStart="12dp" android:paddingStart="12dp"
android:paddingEnd="12dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="vertical"
android:layout_marginStart="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="4dp"
android:paddingBottom="6dp" android:paddingBottom="6dp"
android:text="Client Code" android:text="Client Code"
android:textColor="@color/brand_text_dark" android:textColor="@color/brand_text_dark"
@ -94,9 +93,49 @@
android:paddingEnd="12dp" android:paddingEnd="12dp"
android:tag="client_code"/> android:tag="client_code"/>
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:layout_marginStart="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="12dp"
android:paddingBottom="6dp"
android:text="Coach Code"
android:textColor="@color/brand_text_dark"
android:textSize="12sp" />
<EditText
android:id="@+id/coachEditText"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_field_locked"
android:ems="10"
android:inputType="none"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:cursorVisible="false"
android:longClickable="false"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:drawableEnd="@drawable/ic_lock_24"
android:drawablePadding="8dp"
android:textColor="@color/brand_text_dark"
android:textStyle="bold"
android:tag="coach_code"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
<!-- NEU: Statuszeile (Session-Alter & Online/Offline) --> <!-- Session/Online -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -109,6 +148,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Session: —" android:text="Session: —"
android:textColor="@color/brand_text_dark" android:textColor="@color/brand_text_dark"
android:textSize="13sp" /> android:textSize="13sp" />
@ -119,6 +159,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Offline" android:text="Offline"
android:textStyle="bold" android:textStyle="bold"
android:layout_marginEnd="8dp"
android:textSize="13sp" android:textSize="13sp"
android:textColor="#C62828" android:textColor="#C62828"
android:paddingStart="12dp"/> android:paddingStart="12dp"/>