Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2020 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package androidx.ui.material.studies.rally |
| 18 | |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 19 | import android.annotation.SuppressLint |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 20 | import androidx.compose.Composable |
| 21 | import androidx.compose.state |
| 22 | import androidx.ui.core.Text |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 23 | import androidx.ui.foundation.VerticalScroller |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 24 | import androidx.ui.layout.Arrangement |
| 25 | import androidx.ui.layout.Column |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 26 | import androidx.ui.layout.EdgeInsets |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 27 | import androidx.ui.layout.LayoutGravity |
| 28 | import androidx.ui.layout.LayoutHeight |
| 29 | import androidx.ui.layout.LayoutPadding |
| 30 | import androidx.ui.layout.LayoutWidth |
| 31 | import androidx.ui.layout.Row |
| 32 | import androidx.ui.layout.Spacer |
| 33 | import androidx.ui.material.Divider |
| 34 | import androidx.ui.material.MaterialTheme |
| 35 | import androidx.ui.material.TextButton |
| 36 | import androidx.ui.material.icons.Icons |
Andrey Kulikov | 602ef01 | 2020-03-05 18:12:54 +0000 | [diff] [blame] | 37 | import androidx.ui.material.Card |
Louis Pullen-Freilich | a5a9e15 | 2020-03-12 23:19:53 +0000 | [diff] [blame^] | 38 | import androidx.ui.material.IconButton |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 39 | import androidx.ui.unit.dp |
| 40 | import java.util.Locale |
| 41 | |
| 42 | @Composable |
| 43 | fun OverviewBody() { |
| 44 | VerticalScroller { |
| 45 | Column(modifier = LayoutPadding(16.dp)) { |
| 46 | AlertCard() |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 47 | Spacer(LayoutHeight(RallyDefaultPadding)) |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 48 | AccountsCard() |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 49 | Spacer(LayoutHeight(RallyDefaultPadding)) |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 50 | BillsCard() |
| 51 | } |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | /** |
| 56 | * The Alerts card within the Rally Overview screen. |
| 57 | */ |
| 58 | @Composable |
| 59 | private fun AlertCard() { |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 60 | var openDialog by state { false } |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 61 | val alertMessage = "Heads up, you've used up 90% of your Shopping budget for this month." |
| 62 | |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 63 | if (openDialog) { |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 64 | RallyAlertDialog( |
| 65 | onDismiss = { |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 66 | openDialog = false |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 67 | }, |
| 68 | bodyText = alertMessage, |
| 69 | buttonText = "Dismiss".toUpperCase(Locale.getDefault()) |
| 70 | ) |
| 71 | } |
| 72 | Card { |
| 73 | Column { |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 74 | AlertHeader({ openDialog = true }) |
| 75 | RallyDivider( |
| 76 | modifier = LayoutPadding(start = RallyDefaultPadding, end = RallyDefaultPadding) |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 77 | ) |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 78 | AlertItem(alertMessage) |
| 79 | } |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | @Composable |
| 84 | private fun AlertHeader(onClickSeeAll: () -> Unit) { |
| 85 | Row( |
| 86 | modifier = LayoutPadding(RallyDefaultPadding) + LayoutWidth.Fill, |
| 87 | arrangement = Arrangement.SpaceBetween |
| 88 | ) { |
| 89 | Text( |
| 90 | text = "Alerts", |
| 91 | style = MaterialTheme.typography().subtitle2, |
| 92 | modifier = LayoutGravity.Center |
| 93 | ) |
| 94 | TextButton( |
| 95 | onClick = onClickSeeAll, |
Andrey Kulikov | 96938ff | 2020-03-04 16:39:10 +0000 | [diff] [blame] | 96 | innerPadding = EdgeInsets(0.dp), |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 97 | modifier = LayoutGravity.Center |
| 98 | ) { |
| 99 | Text("SEE ALL") |
| 100 | } |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | @Composable |
| 105 | private fun AlertItem(message: String) { |
| 106 | // TODO: Make alerts into a data structure |
| 107 | Row( |
| 108 | modifier = LayoutPadding(RallyDefaultPadding), |
| 109 | arrangement = Arrangement.SpaceBetween |
| 110 | ) { |
| 111 | Text( |
| 112 | style = MaterialTheme.typography().h3, |
Mihai Popa | 9fcfaeb | 2020-03-09 17:50:28 +0000 | [diff] [blame] | 113 | modifier = LayoutWeight(1f), |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 114 | text = message |
| 115 | ) |
| 116 | IconButton( |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 117 | onClick = {}, |
| 118 | modifier = LayoutGravity.Top |
Louis Pullen-Freilich | a5a9e15 | 2020-03-12 23:19:53 +0000 | [diff] [blame^] | 119 | ) { |
| 120 | Icon(Icons.Filled.Sort) |
| 121 | } |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 122 | } |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * Base structure for cards in the Overview screen. |
| 127 | */ |
| 128 | @SuppressLint("UnnecessaryLambdaCreation") |
| 129 | @Composable |
| 130 | private fun <T> OverviewScreenCard( |
| 131 | title: String, |
| 132 | amount: Float, |
| 133 | onClickSeeAll: () -> Unit, |
| 134 | data: List<T>, |
| 135 | row: @Composable() (T) -> Unit |
| 136 | ) { |
| 137 | Card { |
| 138 | Column { |
| 139 | Column(modifier = LayoutPadding(RallyDefaultPadding)) { |
| 140 | Text(text = title, style = MaterialTheme.typography().subtitle2) |
| 141 | val amountText = "$" + formatAmount(amount) |
| 142 | Text(text = amountText, style = MaterialTheme.typography().h2) |
| 143 | } |
| 144 | Divider(color = rallyGreen, height = 1.dp) |
| 145 | Column(LayoutPadding(start = 16.dp, top = 4.dp, end = 8.dp)) { |
| 146 | data.take(3).forEach { row(it) } |
| 147 | SeeAllButton(onClick = onClickSeeAll) |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 148 | } |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * The Accounts card within the Rally Overview screen. |
| 155 | */ |
| 156 | @Composable |
| 157 | private fun AccountsCard() { |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 158 | val amount = UserData.accounts.map { account -> account.balance }.sum() |
| 159 | OverviewScreenCard( |
| 160 | title = "Accounts", |
| 161 | amount = amount, |
| 162 | onClickSeeAll = { |
| 163 | // TODO: Figure out navigation |
| 164 | }, |
| 165 | data = UserData.accounts |
| 166 | ) { account -> |
| 167 | AccountRow( |
| 168 | name = account.name, |
| 169 | number = account.number, |
| 170 | amount = account.balance, |
| 171 | color = account.color |
| 172 | ) |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 173 | } |
| 174 | } |
| 175 | |
| 176 | /** |
| 177 | * The Bills card within the Rally Overview screen. |
| 178 | */ |
| 179 | @Composable |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 180 | private fun BillsCard() { |
| 181 | val amount = UserData.bills.map { bill -> bill.amount }.sum() |
| 182 | OverviewScreenCard( |
| 183 | title = "Bills", |
| 184 | amount = amount, |
| 185 | onClickSeeAll = { |
| 186 | // TODO: Figure out navigation |
| 187 | }, |
| 188 | data = UserData.bills |
| 189 | ) { bill -> |
| 190 | BillRow( |
| 191 | name = bill.name, |
| 192 | due = bill.due, |
| 193 | amount = bill.amount, |
| 194 | color = bill.color |
| 195 | ) |
Clara Bayarri | 255d76a | 2020-02-12 12:23:09 +0000 | [diff] [blame] | 196 | } |
Clara Bayarri | 7372573 | 2020-02-12 18:27:38 +0000 | [diff] [blame] | 197 | } |
| 198 | |
| 199 | @Composable |
| 200 | private fun SeeAllButton(onClick: () -> Unit) { |
| 201 | TextButton( |
| 202 | onClick = onClick, |
| 203 | modifier = LayoutHeight(44.dp) + LayoutWidth.Fill |
| 204 | ) { |
| 205 | Text("SEE ALL") |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | private val RallyDefaultPadding = 12.dp |