Skip to content
Snippets Groups Projects
Commit 56528976 authored by scimmiamorta's avatar scimmiamorta
Browse files

First Commit

parent 52080cc7
Branches master
No related tags found
No related merge requests found
Showing
with 285 additions and 93 deletions
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
......
...@@ -26,7 +26,6 @@ import com.example.taskmanagement.task.HomeFragment ...@@ -26,7 +26,6 @@ import com.example.taskmanagement.task.HomeFragment
import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentSnapshot import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.QuerySnapshot
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
...@@ -82,9 +81,14 @@ class ProfileFragment : Fragment() { ...@@ -82,9 +81,14 @@ class ProfileFragment : Fragment() {
binding.assignedTasksList.adapter = taskAdapter binding.assignedTasksList.adapter = taskAdapter
binding.assignedTasksList.isNestedScrollingEnabled = true binding.assignedTasksList.isNestedScrollingEnabled = true
loadUserData()
loadProfileImage() loadProfileImage()
setupListeners()
loadUserDataByRole()
return binding.root
}
private fun setupListeners() {
binding.buttonEditProfile.setOnClickListener { binding.buttonEditProfile.setOnClickListener {
findNavController().navigate(R.id.action_profileFragment_to_editProfileFragment) findNavController().navigate(R.id.action_profileFragment_to_editProfileFragment)
} }
...@@ -99,8 +103,6 @@ class ProfileFragment : Fragment() { ...@@ -99,8 +103,6 @@ class ProfileFragment : Fragment() {
binding.profileImage.setOnClickListener { binding.profileImage.setOnClickListener {
checkPermissions() checkPermissions()
} }
return binding.root
} }
private fun checkPermissions() { private fun checkPermissions() {
...@@ -129,7 +131,6 @@ class ProfileFragment : Fragment() { ...@@ -129,7 +131,6 @@ class ProfileFragment : Fragment() {
} }
} }
private fun openGallery() { private fun openGallery() {
pickImageLauncher.launch("image/*") pickImageLauncher.launch("image/*")
} }
...@@ -150,8 +151,7 @@ class ProfileFragment : Fragment() { ...@@ -150,8 +151,7 @@ class ProfileFragment : Fragment() {
context, context,
getString(R.string.error_saving_profile_image), getString(R.string.error_saving_profile_image),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
) ).show()
.show()
} }
} }
...@@ -173,129 +173,307 @@ class ProfileFragment : Fragment() { ...@@ -173,129 +173,307 @@ class ProfileFragment : Fragment() {
binding.profileImage.setImageBitmap(circularBitmap) binding.profileImage.setImageBitmap(circularBitmap)
} }
private fun loadUserDataByRole() {
private fun loadUserData() {
val userId = firebaseAuth!!.currentUser!!.email
val sharedPrefs = val sharedPrefs =
requireContext().getSharedPreferences("TaskManagerPrefs", Context.MODE_PRIVATE) requireContext().getSharedPreferences("TaskManagerPrefs", Context.MODE_PRIVATE)
val role = sharedPrefs.getString("role", "defaultRole") val role = sharedPrefs.getString("role", "defaultRole")
if (role == "PM") {
binding.taskListAssigned.visibility = View.GONE when (role) {
"PM" -> loadDataForPM()
"PL" -> loadDataForPL()
"Dev" -> loadDataForDEV()
else -> Toast.makeText(
context,
getString(R.string.user_role_not_found),
Toast.LENGTH_SHORT
).show()
} }
}
if (userId != null) { private fun loadDataForPM() {
firestore!!.collection("usersData") binding.statistics.visibility = View.GONE
.document(userId) loadBasicUserData()
.get() loadTasksCreatedByPM()
.addOnSuccessListener { document: DocumentSnapshot -> }
val firstName = document.getString("firstName")
val lastName = document.getString("lastName") private fun loadDataForPL() {
val skills = document.getString("skills") loadBasicUserData()
loadTasksAssignedToPL()
if (!firstName.isNullOrEmpty() && !lastName.isNullOrEmpty()) { loadSubTaskStatistics("PL")
binding.userName.text = getString(R.string.user_name, firstName, userId) }
binding.welcomeMessage.text = getString(R.string.welcome_message, firstName)
private fun loadDataForDEV() {
} else { loadBasicUserData()
val email = firebaseAuth!!.currentUser!!.email loadTasksAssignedToDev()
binding.userName.text = email loadSubTaskStatistics("Dev")
binding.welcomeMessage.text = getString(R.string.welcome_message, email) }
}
binding.skillsList.text = skills ?: "Nessuna skill disponibile" private fun loadBasicUserData() {
val userId = firebaseAuth!!.currentUser!!.email
firestore!!.collection("usersData")
.document(userId!!)
.get()
.addOnSuccessListener { document: DocumentSnapshot ->
val firstName = document.getString("firstName")
val lastName = document.getString("lastName")
val skills = document.getString("skills")
if (!firstName.isNullOrEmpty() && !lastName.isNullOrEmpty()) {
binding.userName.text = getString(R.string.user_name, firstName, userId)
binding.welcomeMessage.text = getString(R.string.welcome_message, firstName)
} else {
val email = firebaseAuth!!.currentUser!!.email
binding.userName.text = email
binding.welcomeMessage.text = getString(R.string.welcome_message, email)
} }
.addOnFailureListener {
Toast.makeText( binding.skillsList.text = skills ?: getString(R.string.no_skills_available)
context, }
getString(R.string.error_loading_users), .addOnFailureListener {
Toast.LENGTH_SHORT Toast.makeText(
).show() context,
getString(R.string.error_loading_users),
Toast.LENGTH_SHORT
).show()
}
}
private fun loadTasksCreatedByPM() {
val userId = firebaseAuth!!.currentUser!!.email
firestore!!.collection("tasks")
.whereEqualTo("createdBy", userId) // Filtra i task creati dal PM
.get()
.addOnSuccessListener { tasksSnapshot ->
taskList.clear()
for (task in tasksSnapshot) {
val taskName = task.getString("name")
if (!taskName.isNullOrEmpty()) {
taskList.add(taskName)
}
} }
}
taskAdapter!!.notifyDataSetChanged()
listViewHeight(binding.assignedTasksList)
}
.addOnFailureListener {
Toast.makeText(
context,
getString(R.string.error_loading_tasks),
Toast.LENGTH_SHORT
).show()
}
}
private fun loadTasksAssignedToPL() {
val userId = firebaseAuth!!.currentUser!!.email
firestore!!.collection("tasks") firestore!!.collection("tasks")
.whereEqualTo("assignedTo", userId) .whereEqualTo("assignedTo", userId)
.get() .get()
.addOnSuccessListener { queryDocumentSnapshots: QuerySnapshot -> .addOnSuccessListener { tasksSnapshot ->
taskList.clear() taskList.clear()
for (snapshot in queryDocumentSnapshots) {
val taskName = snapshot.getString("name") for (task in tasksSnapshot) {
if (taskName != null) { val taskName = task.getString("name")
if (!taskName.isNullOrEmpty()) {
taskList.add(taskName) taskList.add(taskName)
} }
} }
taskAdapter!!.notifyDataSetChanged() taskAdapter!!.notifyDataSetChanged()
listViewHeight(binding.assignedTasksList) listViewHeight(binding.assignedTasksList)
if (tasksSnapshot.isEmpty) {
Toast.makeText(
context,
getString(R.string.error_loading_tasks),
Toast.LENGTH_SHORT
).show()
}
} }
.addOnFailureListener { .addOnFailureListener {
Toast.makeText(context, getString(R.string.error_loading_tasks), Toast.LENGTH_SHORT) Toast.makeText(context, getString(R.string.error_loading_tasks), Toast.LENGTH_SHORT)
.show() .show()
} }
}
private fun loadTasksAssignedToDev() {
val userId = firebaseAuth!!.currentUser!!.email
firestore!!.collection("tasks") firestore!!.collection("tasks")
.whereEqualTo("assignedTo", userId)
.get() .get()
.addOnSuccessListener { tasksSnapshot -> .addOnSuccessListener { tasksSnapshot ->
var completedCount = 0 taskList.clear()
var assignedCount = 0
var toDoCount = 0
val taskCount = tasksSnapshot.size()
var tasksProcessed = 0 var tasksProcessed = 0
if (taskCount == 0) {
updateStatistics(completedCount, assignedCount, toDoCount)
return@addOnSuccessListener
}
for (task in tasksSnapshot) { for (task in tasksSnapshot) {
val taskId = task.id val taskId = task.id
val subTaskQuery = if (role == "PL") { firestore!!.collection("tasks")
firestore!!.collection("tasks").document(taskId).collection("subTasks") .document(taskId)
} else { .collection("subTasks")
firestore!!.collection("tasks") .whereEqualTo("assignedTo", userId)
.document(taskId) .get()
.collection("subTasks")
.whereEqualTo("assignedTo", userId)
}
subTaskQuery.get()
.addOnSuccessListener { subTasksSnapshot -> .addOnSuccessListener { subTasksSnapshot ->
for (subTask in subTasksSnapshot) { for (subTask in subTasksSnapshot) {
val subTaskStatus = subTask.getLong("status")?.toInt() val subTaskName = subTask.getString("name")
when (subTaskStatus) { if (subTaskName != null) {
2 -> completedCount++ taskList.add(subTaskName)
1 -> assignedCount++
0 -> toDoCount++
} }
} }
tasksProcessed++ tasksProcessed++
if (tasksProcessed == tasksSnapshot.size()) {
if (tasksProcessed == taskCount) { taskAdapter!!.notifyDataSetChanged()
updateStatistics(completedCount, assignedCount, toDoCount) listViewHeight(binding.assignedTasksList)
} }
} }
.addOnFailureListener { .addOnFailureListener {
tasksProcessed++
if (tasksProcessed == tasksSnapshot.size()) {
taskAdapter!!.notifyDataSetChanged()
listViewHeight(binding.assignedTasksList)
}
Log.e( Log.e(
"ProfileFragment", "ProfileFragment",
"Errore nel recupero dei sottotask per il task $taskId" "Errore caricamento dei sottotask per il task $taskId"
) )
tasksProcessed++
if (tasksProcessed == taskCount) {
updateStatistics(completedCount, assignedCount, toDoCount)
}
} }
} }
if (tasksSnapshot.isEmpty) {
taskAdapter!!.notifyDataSetChanged()
listViewHeight(binding.assignedTasksList)
}
} }
.addOnFailureListener { .addOnFailureListener {
Toast.makeText(context, getString(R.string.error_loading_tasks), Toast.LENGTH_SHORT) Toast.makeText(context, getString(R.string.error_loading_tasks), Toast.LENGTH_SHORT)
.show() .show()
} }
}
private fun loadSubTaskStatistics(role: String) {
val userId = firebaseAuth!!.currentUser!!.email
if (role == "Dev") {
firestore!!.collection("tasks")
.get()
.addOnSuccessListener { tasksSnapshot ->
var completedCount = 0
var assignedCount = 0
var toDoCount = 0
var tasksProcessed = 0
val taskCount = tasksSnapshot.size()
if (taskCount == 0) {
updateStatistics(completedCount, assignedCount, toDoCount)
return@addOnSuccessListener
}
for (task in tasksSnapshot) {
val taskId = task.id
firestore!!.collection("tasks")
.document(taskId)
.collection("subTasks")
.whereEqualTo("assignedTo", userId)
.get()
.addOnSuccessListener { subTasksSnapshot ->
for (subTask in subTasksSnapshot) {
val subTaskStatus = subTask.getLong("status")?.toInt()
when (subTaskStatus) {
2 -> completedCount++
1 -> assignedCount++
0 -> toDoCount++
}
}
tasksProcessed++
if (tasksProcessed == taskCount) {
updateStatistics(completedCount, assignedCount, toDoCount)
}
}
.addOnFailureListener {
tasksProcessed++
if (tasksProcessed == taskCount) {
updateStatistics(completedCount, assignedCount, toDoCount)
}
}
}
}
.addOnFailureListener {
Toast.makeText(
context,
getString(R.string.error_loading_tasks),
Toast.LENGTH_SHORT
)
.show()
}
} else {
firestore!!.collection("tasks")
.whereEqualTo("assignedTo", userId)
.get()
.addOnSuccessListener { tasksSnapshot ->
var completedCount = 0
var assignedCount = 0
var toDoCount = 0
val taskCount = tasksSnapshot.size()
var tasksProcessed = 0
if (taskCount == 0) {
updateStatistics(completedCount, assignedCount, toDoCount)
return@addOnSuccessListener
}
for (task in tasksSnapshot) {
val taskId = task.id
val subTaskQuery =
firestore!!.collection("tasks").document(taskId).collection("subTasks")
subTaskQuery.get()
.addOnSuccessListener { subTasksSnapshot ->
for (subTask in subTasksSnapshot) {
val subTaskStatus = subTask.getLong("status")?.toInt()
when (subTaskStatus) {
2 -> completedCount++
1 -> assignedCount++
0 -> toDoCount++
}
}
tasksProcessed++
if (tasksProcessed == taskCount) {
updateStatistics(completedCount, assignedCount, toDoCount)
}
}
.addOnFailureListener {
Log.e(
"ProfileFragment",
"Errore nel recupero dei sottotask per il task $taskId"
)
tasksProcessed++
if (tasksProcessed == taskCount) {
updateStatistics(completedCount, assignedCount, toDoCount)
}
}
}
}
.addOnFailureListener {
Toast.makeText(
context,
getString(R.string.error_loading_tasks),
Toast.LENGTH_SHORT
)
.show()
}
}
} }
private fun updateStatistics(completed: Int, assigned: Int, toDo: Int) { private fun updateStatistics(completed: Int, assigned: Int, toDo: Int) {
......
...@@ -291,7 +291,6 @@ class HomeFragment : Fragment() { ...@@ -291,7 +291,6 @@ class HomeFragment : Fragment() {
val sharedPrefs = val sharedPrefs =
requireContext().getSharedPreferences("TaskManagerPrefs", Context.MODE_PRIVATE) requireContext().getSharedPreferences("TaskManagerPrefs", Context.MODE_PRIVATE)
val role = sharedPrefs.getString("role", "defaultRole") val role = sharedPrefs.getString("role", "defaultRole")
Log.d("HomeFragment", "Role: $role")
if (role == "PM") { if (role == "PM") {
return return
......
...@@ -69,6 +69,9 @@ class ModifySubTaskFragment : Fragment() { ...@@ -69,6 +69,9 @@ class ModifySubTaskFragment : Fragment() {
} }
private fun loadSubtaskData() { private fun loadSubtaskData() {
val sharedPrefs =
requireContext().getSharedPreferences("TaskManagerPrefs", Context.MODE_PRIVATE)
val role = sharedPrefs.getString("role", "defaultRole")
db.collection("tasks") db.collection("tasks")
.document(taskId ?: "") .document(taskId ?: "")
.collection("subTasks") .collection("subTasks")
...@@ -79,10 +82,7 @@ class ModifySubTaskFragment : Fragment() { ...@@ -79,10 +82,7 @@ class ModifySubTaskFragment : Fragment() {
val subtask = document.toObject(SubTask::class.java) val subtask = document.toObject(SubTask::class.java)
subtask?.let { subtask?.let {
val currentUserEmail = mAuth.currentUser?.email val currentUserEmail = mAuth.currentUser?.email
Log.e("ModifySubTaskFragment", "Current User Email: $currentUserEmail") if (currentUserEmail == subtask.createdBy || currentUserEmail == subtask.assignedTo || role == "PL") {
Log.e("ModifySubTaskFragment", "Subtask Created By: ${subtask.createdBy}")
Log.e("ModifySubTaskFragment", "Subtask Assigned To: ${subtask.assignedTo}")
if (currentUserEmail == subtask.createdBy || currentUserEmail == subtask.assignedTo) {
populateFields(it) populateFields(it)
} else { } else {
Toast.makeText( Toast.makeText(
...@@ -214,7 +214,7 @@ class ModifySubTaskFragment : Fragment() { ...@@ -214,7 +214,7 @@ class ModifySubTaskFragment : Fragment() {
) )
binding.statusDropdown.setAdapter(adapter) binding.statusDropdown.setAdapter(adapter)
if (status in statusOptions.indices) { if (status in statusOptions.indices) {
binding.priorityDropdown.setText(statusOptions[status], false) binding.statusDropdown.setText(statusOptions[status], false)
} }
} }
......
...@@ -310,6 +310,12 @@ class SearchFragment : Fragment() { ...@@ -310,6 +310,12 @@ class SearchFragment : Fragment() {
} }
private fun onTaskClick(task: Task) { private fun onTaskClick(task: Task) {
val sharedPrefs =
requireContext().getSharedPreferences("TaskManagerPrefs", Context.MODE_PRIVATE)
val role = sharedPrefs.getString("role", "defaultRole")
if (role == "PM") {
return
}
val taskId = taskIdMap[task.name] val taskId = taskIdMap[task.name]
Log.e("SearchFragment", "Task ID: $taskId") Log.e("SearchFragment", "Task ID: $taskId")
val bundle = Bundle().apply { val bundle = Bundle().apply {
......
...@@ -72,7 +72,8 @@ ...@@ -72,7 +72,8 @@
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/subtaskName" android:id="@+id/subtaskName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
android:inputType="textCapSentences" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
...@@ -85,7 +86,8 @@ ...@@ -85,7 +86,8 @@
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/subtaskDescription" android:id="@+id/subtaskDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
android:inputType="textCapSentences" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
......
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/taskName" android:id="@+id/taskName"
android:inputType="textCapSentences"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
...@@ -79,10 +80,12 @@ ...@@ -79,10 +80,12 @@
style="@style/Widget.Material3.TextInputLayout.FilledBox" style="@style/Widget.Material3.TextInputLayout.FilledBox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/task_description"> android:hint="@string/task_description"
>
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/taskDescription" android:id="@+id/taskDescription"
android:inputType="textCapSentences"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
android:layout_weight="1" android:layout_weight="1"
android:autofillHints="" android:autofillHints=""
android:hint="@string/write_a_message" android:hint="@string/write_a_message"
android:inputType="text" android:inputType="textCapSentences"
android:padding="8dp" /> android:padding="8dp" />
<Button <Button
......
...@@ -113,6 +113,7 @@ ...@@ -113,6 +113,7 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/statistics"
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"
...@@ -189,7 +190,7 @@ ...@@ -189,7 +190,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="@string/complete" android:text="@string/completed"
android:textColor="@color/black" /> android:textColor="@color/black" />
<TextView <TextView
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
tools:context=".task.SearchFragment"> tools:context=".task.SearchFragment">
<!-- Titolo del Fragment -->
<TextView <TextView
android:id="@+id/fragmentTitle" android:id="@+id/fragmentTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
...@@ -29,6 +28,7 @@ ...@@ -29,6 +28,7 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:contentDescription="@string/find_tasks" android:contentDescription="@string/find_tasks"
android:inputType="textCapSentences"
android:queryHint="@string/find_tasks" android:queryHint="@string/find_tasks"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
......
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
android:id="@+id/search_view" android:id="@+id/search_view"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:queryHint="Cerca Task" android:inputType="textCapSentences"
android:queryHint="@string/find_tasks"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/fragmentTitle" /> app:layout_constraintTop_toBottomOf="@id/fragmentTitle" />
......
...@@ -175,5 +175,7 @@ ...@@ -175,5 +175,7 @@
<string name="error_loading_profile_image">Errore caricamento immagine profilo</string> <string name="error_loading_profile_image">Errore caricamento immagine profilo</string>
<string name="task_id_not_found">Task ID non trovato</string> <string name="task_id_not_found">Task ID non trovato</string>
<string name="error_not_authorized">Non sei autorizzato a modificare questo sottotask.</string> <string name="error_not_authorized">Non sei autorizzato a modificare questo sottotask.</string>
<string name="no_skills_available">No skills presenti</string>
<string name="assigned">Assegnati</string>
</resources> </resources>
\ No newline at end of file
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
<string name="error_retrieving_role">Error retrieving role</string> <string name="error_retrieving_role">Error retrieving role</string>
<string name="failed_to_add_subtask">Failed to add subtask: %1$s</string> <string name="failed_to_add_subtask">Failed to add subtask: %1$s</string>
<string name="subtask_added_successfully">Subtask added successfully</string> <string name="subtask_added_successfully">Subtask added successfully</string>
<string name="assigned" translatable="false">Assigned</string> <string name="assigned">Assigned</string>
<string name="high">High</string> <string name="high">High</string>
<string name="medium">Medium</string> <string name="medium">Medium</string>
<string name="low">Low</string> <string name="low">Low</string>
...@@ -196,5 +196,6 @@ ...@@ -196,5 +196,6 @@
<string name="error_loading_profile_image">Error loading profile image</string> <string name="error_loading_profile_image">Error loading profile image</string>
<string name="task_id_not_found">Task ID not found</string> <string name="task_id_not_found">Task ID not found</string>
<string name="error_not_authorized">Not authorized</string> <string name="error_not_authorized">Not authorized</string>
<string name="no_skills_available">No skills available</string>
</resources> </resources>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment