@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
77import androidx.compose.foundation.layout.padding
88import androidx.compose.foundation.shape.RoundedCornerShape
99import androidx.compose.material3.Button
10+ import androidx.compose.material3.ButtonDefaults
1011import androidx.compose.material3.Surface
1112import androidx.compose.material3.Text
1213import androidx.compose.runtime.Composable
@@ -17,72 +18,201 @@ import androidx.compose.ui.text.font.FontStyle
1718import androidx.compose.ui.tooling.preview.Preview
1819import androidx.compose.ui.unit.dp
1920import androidx.compose.ui.unit.sp
21+ import com.example.senpos.data.models.IntakeStatus
22+ import com.example.senpos.viewmodels.IntakeCardUiModel
23+ import com.example.senpos.viewmodels.OverdueIntakeUiModel
2024import com.example.senpos.ui.theme.SenPosTheme
25+ import java.text.SimpleDateFormat
26+ import java.util.Date
27+ import java.util.Locale
2128
2229@Composable
23- fun IntakeComponent (today : Boolean , upcoming : Boolean ) {
24- Surface (modifier = Modifier .padding(horizontal = 16 .dp, vertical = 8 .dp),
25- color = Color (0xFFFF6C00 ),
26- shape = RoundedCornerShape (50 .dp)
30+ fun IntakeComponent (
31+ intake : IntakeCardUiModel ,
32+ onTake : (String ) -> Unit
33+ ) {
34+ val alreadyActioned = intake.status != IntakeStatus .PENDING
35+
36+ IntakeCard {
37+ IntakeInfo (
38+ drugName = intake.drugName,
39+ dosage = intake.dosage,
40+ quantity = intake.quantity,
41+ time = formatTime(intake.scheduledTime)
2742 )
28- {
29- Column (modifier = Modifier .padding(top = 16 .dp, bottom = 16 .dp, start = 8 .dp, end = 8 .dp)) {
30- Row (
31- modifier = Modifier
32- .fillMaxWidth()
33- .padding(bottom = 8 .dp),
34- horizontalArrangement = Arrangement .SpaceEvenly ,
35- verticalAlignment = Alignment .CenterVertically
43+ Row (
44+ modifier = Modifier .fillMaxWidth(),
45+ horizontalArrangement = Arrangement .Center
46+ ) {
47+ Button (
48+ onClick = { onTake(intake.intakeId) },
49+ enabled = ! intake.isUpcoming && ! alreadyActioned,
50+ colors = ButtonDefaults .buttonColors(
51+ containerColor = Color .White ,
52+ contentColor = Color (0xFFFF6C00 ),
53+ disabledContainerColor = Color .White .copy(alpha = 0.4f ),
54+ disabledContentColor = Color .White .copy(alpha = 0.6f )
55+ )
3656 ) {
3757 Text (
38- text = " Paracetamol 500g" ,
39- color = Color (0xFFFFFFFF ),
40- fontSize = 24 .sp
58+ text = when {
59+ intake.isUpcoming -> " Upcoming"
60+ alreadyActioned -> if (intake.status == IntakeStatus .TAKEN ) " Taken ✓" else " Missed"
61+ else -> " I took it"
62+ }
4163 )
64+ }
65+ }
66+ }
67+ }
4268
43- Text (
44- text = " 1 pill" ,
45- color = Color (0xFFFFFFFF ),
46- fontSize = 20 .sp,
47- fontStyle = FontStyle .Italic
69+
70+ @Composable
71+ fun OverdueIntakeComponent (
72+ intake : OverdueIntakeUiModel ,
73+ onTake : (String ) -> Unit ,
74+ onMiss : (String ) -> Unit
75+ ) {
76+ IntakeCard {
77+ IntakeInfo (
78+ drugName = intake.drugName,
79+ dosage = intake.dosage,
80+ quantity = intake.quantity,
81+ time = formatTime(intake.scheduledTime)
82+ )
83+ Row (
84+ modifier = Modifier .fillMaxWidth(),
85+ horizontalArrangement = Arrangement .SpaceEvenly
86+ ) {
87+ Button (
88+ onClick = { onTake(intake.intakeId) },
89+ colors = ButtonDefaults .buttonColors(
90+ containerColor = Color .White ,
91+ contentColor = Color (0xFFFF6C00 )
4892 )
93+ ) {
94+ Text (" I took it" )
4995 }
50-
51- Row (
52- modifier = Modifier .fillMaxWidth(),
53- horizontalArrangement = Arrangement .SpaceEvenly ,
54- verticalAlignment = Alignment .CenterVertically
96+ Button (
97+ onClick = { onMiss(intake.intakeId) },
98+ colors = ButtonDefaults .buttonColors(
99+ containerColor = Color .White .copy(alpha = 0.4f ),
100+ contentColor = Color .White
101+ )
55102 ) {
56- if (! today) {
57- Button (onClick = { /* TODO*/ }) {
58- Text (
59- text = " I took it"
60- )
61- }
62-
63- Button (onClick = { /* TODO*/ }) {
64- Text (
65- text = " I forgot"
66- )
67- }
68- } else {
69- Button (onClick = { /* TODO*/ }, enabled = ! upcoming) {
70- Text (
71- text = if (! upcoming) " I took it" else " upcoming"
72- )
73- }
74- }
75-
103+ Text (" I missed it" )
76104 }
105+ }
106+ }
107+ }
77108
109+ @Composable
110+ private fun IntakeCard (content : @Composable () -> Unit ) {
111+ Surface (
112+ modifier = Modifier .padding(horizontal = 16 .dp, vertical = 8 .dp),
113+ color = Color (0xFFFF6C00 ),
114+ shape = RoundedCornerShape (50 .dp)
115+ ) {
116+ Column (
117+ modifier = Modifier .padding(top = 16 .dp, bottom = 16 .dp, start = 8 .dp, end = 8 .dp)
118+ ) {
119+ content()
78120 }
79121 }
80122}
123+ @Composable
124+ private fun IntakeInfo (drugName : String , dosage : String , quantity : Int , time : String ) {
125+ // Ligne 1 : nom + dosage
126+ Text (
127+ text = " $drugName $dosage " ,
128+ color = Color .White ,
129+ fontSize = 22 .sp,
130+ modifier = Modifier
131+ .fillMaxWidth()
132+ .padding(start = 8 .dp, bottom = 4 .dp)
133+ )
134+ // Ligne 2 : quantité + heure
135+ Row (
136+ modifier = Modifier
137+ .fillMaxWidth()
138+ .padding(start = 8 .dp, bottom = 8 .dp),
139+ horizontalArrangement = Arrangement .SpaceBetween ,
140+ verticalAlignment = Alignment .CenterVertically
141+ ) {
142+ Text (
143+ text = " $quantity pill${if (quantity > 1 ) " s" else " " } " ,
144+ color = Color .White ,
145+ fontSize = 16 .sp,
146+ fontStyle = FontStyle .Italic
147+ )
148+ Text (
149+ text = time,
150+ color = Color .White ,
151+ fontSize = 16 .sp,
152+ modifier = Modifier .padding(end = 8 .dp)
153+ )
154+ }
155+ }
156+
157+ private fun formatTime (timestamp : Long ): String =
158+ SimpleDateFormat (" HH:mm" , Locale .getDefault()).format(Date (timestamp))
159+
160+
161+ @Preview
162+ @Composable
163+ fun IntakeTodayPreview () {
164+ SenPosTheme {
165+ IntakeComponent (
166+ intake = IntakeCardUiModel (
167+ intakeId = " preview_1" ,
168+ drugName = " Doliprane" ,
169+ dosage = " 1000mg" ,
170+ form = " Tablet" ,
171+ quantity = 1 ,
172+ scheduledTime = System .currentTimeMillis() - 3_600_000 , // 1h ago
173+ status = IntakeStatus .PENDING ,
174+ isUpcoming = false
175+ ),
176+ onTake = {}
177+ )
178+ }
179+ }
81180
181+ @Preview
82182@Composable
183+ fun IntakeUpcomingPreview () {
184+ SenPosTheme {
185+ IntakeComponent (
186+ intake = IntakeCardUiModel (
187+ intakeId = " preview_2" ,
188+ drugName = " Metformine" ,
189+ dosage = " 500mg" ,
190+ form = " Tablet" ,
191+ quantity = 1 ,
192+ scheduledTime = System .currentTimeMillis() + 3_600_000 , // in 1h
193+ status = IntakeStatus .PENDING ,
194+ isUpcoming = true
195+ ),
196+ onTake = {}
197+ )
198+ }
199+ }
200+
83201@Preview
84- fun IntakePreview () {
202+ @Composable
203+ fun OverdueIntakePreview () {
85204 SenPosTheme {
86- IntakeComponent (today = true , upcoming = true )
205+ OverdueIntakeComponent (
206+ intake = OverdueIntakeUiModel (
207+ intakeId = " preview_3" ,
208+ drugName = " Amlodipine" ,
209+ dosage = " 5mg" ,
210+ form = " Tablet" ,
211+ quantity = 2 ,
212+ scheduledTime = System .currentTimeMillis() - 86_400_000 // yesterday
213+ ),
214+ onTake = {},
215+ onMiss = {}
216+ )
87217 }
88218}
0 commit comments