TecnoSamp

SISTEMA COM GOOGLE MAPS E RODAPÉ

Apr 20th, 2026 (edited)
17
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.28 KB | None | 0 0
  1. package com.example.consultacnpj
  2.  
  3. import android.os.Bundle
  4. import androidx.core.net.toUri
  5. import androidx.compose.ui.text.style.TextAlign
  6. import androidx.compose.ui.platform.LocalContext
  7. import android.content.Intent
  8. import android.net.Uri
  9. import androidx.activity.ComponentActivity
  10. import androidx.activity.compose.setContent
  11. import androidx.compose.foundation.layout.*
  12. import androidx.compose.foundation.rememberScrollState
  13. import androidx.compose.foundation.verticalScroll
  14. import androidx.compose.material.icons.Icons
  15. import androidx.compose.material.icons.filled.*
  16. import androidx.compose.material.icons.automirrored.filled.List
  17. import androidx.compose.material.icons.automirrored.filled.Assignment
  18. import androidx.compose.material3.*
  19. import androidx.compose.runtime.*
  20. import androidx.compose.ui.Alignment
  21. import androidx.compose.ui.Modifier
  22. import androidx.compose.ui.graphics.Color
  23. import androidx.compose.ui.unit.dp
  24. import com.example.consultacnpj.ui.theme.ConsultaCNPJTheme
  25. import kotlinx.coroutines.launch
  26. import java.text.NumberFormat
  27. import java.util.Locale
  28.  
  29. @OptIn(ExperimentalMaterial3Api::class)
  30. class MainActivity : ComponentActivity() {
  31. override fun onCreate(savedInstanceState: Bundle?) {
  32. super.onCreate(savedInstanceState)
  33. setContent {
  34. ConsultaCNPJTheme {
  35. Scaffold(
  36. topBar = {
  37. TopAppBar(
  38. title = { Text("TM Consultas", color = Color.White) },
  39. navigationIcon = {
  40. Icon(Icons.Filled.Business, contentDescription = null, tint = Color.White)
  41. },
  42. colors = TopAppBarDefaults.topAppBarColors(
  43. containerColor = Color(0xFF0D47A1)
  44. )
  45. )
  46. },
  47. bottomBar = {
  48. Box(
  49. modifier = Modifier
  50. .fillMaxWidth()
  51. .padding(8.dp),
  52. contentAlignment = Alignment.Center
  53. ) {
  54. Text(
  55. text = "Feito por Marcio Luciano – Para Tassia Tiana",
  56. style = MaterialTheme.typography.titleSmall, // fonte mais bonita
  57. color = Color.Gray,
  58. textAlign = TextAlign.Center
  59. )
  60. }
  61. },
  62. modifier = Modifier.fillMaxSize()
  63. ) { paddingValues ->
  64. ConsultaCnpjApp(modifier = Modifier.padding(paddingValues))
  65. }
  66. }
  67. }
  68. }
  69. }
  70.  
  71.  
  72. @OptIn(ExperimentalMaterial3Api::class)
  73. @Composable
  74. fun ConsultaCnpjApp(modifier: Modifier = Modifier) {
  75. var cnpj by remember { mutableStateOf("") }
  76. var dados by remember { mutableStateOf<CnpjResponse?>(null) }
  77. var carregando by remember { mutableStateOf(false) }
  78. var consultaRealizada by remember { mutableStateOf(false) }
  79. val scope = rememberCoroutineScope()
  80. val scrollState = rememberScrollState()
  81.  
  82. Column(
  83. modifier = modifier
  84. .fillMaxSize()
  85. .padding(16.dp)
  86. .verticalScroll(scrollState),
  87. horizontalAlignment = Alignment.CenterHorizontally
  88. ) {
  89. OutlinedCard(
  90. modifier = Modifier.fillMaxWidth(),
  91. colors = CardDefaults.outlinedCardColors(
  92. containerColor = MaterialTheme.colorScheme.surface
  93. )
  94. ) {
  95. Column(modifier = Modifier.padding(16.dp)) {
  96. Text("Digite para consultar os dados da empresa.",
  97. style = MaterialTheme.typography.titleMedium)
  98. Spacer(modifier = Modifier.height(12.dp))
  99. OutlinedTextField(
  100. value = cnpj,
  101. onValueChange = { input -> cnpj = input.filter { it.isDigit() } },
  102. label = { Text("Digite o CNPJ") },
  103. placeholder = { Text("Ex: 32956169000106") },
  104. leadingIcon = { Icon(Icons.Filled.Search, contentDescription = null) },
  105. modifier = Modifier.fillMaxWidth()
  106. )
  107. if (cnpj.isNotBlank() && cnpj.length < 14) {
  108. Text("CNPJ incompleto (precisa ter 14 dígitos).",
  109. color = Color(0xFFE57373),
  110. style = MaterialTheme.typography.bodySmall,
  111. modifier = Modifier.padding(top = 4.dp))
  112. }
  113. Text("Digite apenas números, sem pontos ou traços.",
  114. style = MaterialTheme.typography.bodySmall,
  115. modifier = Modifier.padding(top = 4.dp))
  116. Spacer(modifier = Modifier.height(12.dp))
  117. Button(
  118. onClick = {
  119. scope.launch {
  120. carregando = true
  121. consultaRealizada = true
  122. try {
  123. val resposta = RetrofitInstance.api.consultarCNPJ(cnpj)
  124. dados = if (resposta.isSuccessful) resposta.body() else null
  125. } catch (_: Exception) {
  126. dados = null
  127. }
  128. carregando = false
  129. }
  130. },
  131. enabled = cnpj.length == 14,
  132. modifier = Modifier.fillMaxWidth(),
  133. colors = ButtonDefaults.buttonColors(
  134. containerColor = Color(0xFF0D47A1), // Azul executivo
  135. contentColor = Color.White
  136. )
  137. ) {
  138. Icon(Icons.Filled.PlayArrow, contentDescription = null, tint = Color.White)
  139. Spacer(modifier = Modifier.width(8.dp))
  140. Text("Consultar")
  141. }
  142. }
  143. }
  144.  
  145. Spacer(modifier = Modifier.height(16.dp))
  146.  
  147. if (carregando) {
  148. CircularProgressIndicator()
  149. } else {
  150. if (consultaRealizada) {
  151. dados?.let {
  152. InfoCard("Registro", Icons.Filled.Info) {
  153. Text("CNPJ: ${it.cnpj}")
  154. Text("Data de Abertura: ${it.abertura}")
  155. Text("Última Atualização: ${it.ultimaAtualizacao}")
  156. }
  157. HorizontalDivider()
  158.  
  159. InfoCard("Dados da Empresa", Icons.Filled.Business) {
  160. Text("Nome: ${it.nome}")
  161. Text("Fantasia: ${it.fantasia}")
  162. }
  163. HorizontalDivider()
  164.  
  165. InfoCard("Situação Cadastral", Icons.Filled.CheckCircle) {
  166. val corSituacao = if (it.situacao == "ATIVA") Color(0xFF4CAF50) else Color(0xFFE57373)
  167. Text("Situação: ${it.situacao} (desde ${it.dataSituacao})", color = corSituacao)
  168. }
  169. HorizontalDivider()
  170.  
  171. InfoCard("Contato", Icons.Filled.Phone) {
  172. Text("Telefone: ${it.telefone}")
  173. Text("Email: ${it.email}")
  174. }
  175. HorizontalDivider()
  176.  
  177. InfoCard("Endereço", Icons.Filled.LocationOn) {
  178. Text("${it.logradouro}, ${it.numero}, ${it.bairro}")
  179. Text("${it.municipio} - ${it.uf}, CEP: ${it.cep}")
  180. }
  181.  
  182. // Botão aparece se o endereço não for vazio
  183. if (!it.logradouro.isNullOrBlank()) {
  184. Spacer(modifier = Modifier.height(12.dp))
  185. val context = LocalContext.current
  186. Button(onClick = {
  187. val enderecoEmpresa = "${it.logradouro}, ${it.numero}, ${it.bairro}, ${it.municipio} - ${it.uf}"
  188. val gmmIntentUri = "https://www.google.com/maps/search/?api=1&query=${Uri.encode(enderecoEmpresa)}".toUri()
  189. val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
  190. mapIntent.setPackage("com.google.android.apps.maps")
  191. context.startActivity(mapIntent)
  192. }) {
  193. Icon(Icons.Filled.LocationOn, contentDescription = null)
  194. Spacer(modifier = Modifier.width(8.dp))
  195. Text("Encontrar esta empresa no Maps")
  196. }
  197. }
  198.  
  199. HorizontalDivider()
  200.  
  201.  
  202.  
  203. InfoCard("Atividade Principal", Icons.Filled.Work) {
  204. Text(it.atividadePrincipal?.firstOrNull()?.descricao ?: "")
  205. }
  206. HorizontalDivider()
  207.  
  208. InfoCard("Atividades Secundárias", Icons.AutoMirrored.Filled.List) {
  209. it.atividadesSecundarias?.forEach { atividade ->
  210. Text("- ${atividade.descricao}")
  211. }
  212. }
  213. HorizontalDivider()
  214.  
  215. InfoCard("Informações Jurídicas", Icons.Filled.Gavel) {
  216. Text("Natureza Jurídica: ${it.naturezaJuridica}")
  217. val capitalFormatado = try {
  218. val valor = it.capitalSocial?.replace(",", ".")?.toDoubleOrNull()
  219. if (valor != null) NumberFormat.getCurrencyInstance(Locale.forLanguageTag("pt-BR")).format(valor)
  220. else "-"
  221. } catch (_: Exception) {
  222. "-"
  223. }
  224. Text("Capital Social: $capitalFormatado")
  225. }
  226. HorizontalDivider()
  227.  
  228. InfoCard("Simples Nacional", Icons.AutoMirrored.Filled.Assignment) {
  229. Text("Optante: ${if (it.simples?.optante == true) "Sim" else "Não"}")
  230. Text("Data de Opção: ${it.simples?.dataOpcao ?: "-"}")
  231. Text("Data de Exclusão: ${it.simples?.dataExclusao ?: "-"}")
  232. }
  233. HorizontalDivider()
  234.  
  235. InfoCard("Sócios/Administradores", Icons.Filled.People) {
  236. it.socios?.forEach { socio ->
  237. Text("- ${socio.nome} (${socio.qualificacao})")
  238. }
  239. }
  240. } ?: run {
  241. if (cnpj.isNotBlank()) {
  242. Row(
  243. verticalAlignment = Alignment.CenterVertically,
  244. horizontalArrangement = Arrangement.Center,
  245. modifier = Modifier.fillMaxWidth()
  246. ) {
  247. Icon(Icons.Filled.ErrorOutline, contentDescription = null, tint = Color(0xFFE57373))
  248. Spacer(modifier = Modifier.width(8.dp))
  249. Text("CNPJ inexistente, confira!", color = Color(0xFFE57373))
  250. }
  251. }
  252. }
  253. }
  254. }
  255. }
  256. }
  257.  
  258. @OptIn(ExperimentalMaterial3Api::class)
  259. @Composable
  260. fun InfoCard(
  261. titulo: String,
  262. icone: androidx.compose.ui.graphics.vector.ImageVector,
  263. conteudo: @Composable ColumnScope.() -> Unit
  264. ) {
  265. OutlinedCard(
  266. modifier = Modifier
  267. .fillMaxWidth()
  268. .padding(vertical = 8.dp),
  269. colors = CardDefaults.outlinedCardColors()
  270. ) {
  271. Column(modifier = Modifier.padding(12.dp)) {
  272. Row(verticalAlignment = Alignment.CenterVertically) {
  273. Icon(icone, contentDescription = null, tint = MaterialTheme.colorScheme.primary)
  274. Spacer(modifier = Modifier.width(8.dp))
  275. Text(titulo, style = MaterialTheme.typography.titleMedium)
  276. }
  277. Spacer(modifier = Modifier.height(4.dp))
  278. conteudo()
  279. }
  280. }
  281. }
  282.  
Advertisement
Add Comment
Please, Sign In to add comment