{"id":119,"date":"2026-07-28T10:20:06","date_gmt":"2026-07-28T10:20:06","guid":{"rendered":"https:\/\/demensdeum.com\/blog\/2026\/07\/28\/mama-calendar\/"},"modified":"2026-07-28T10:20:06","modified_gmt":"2026-07-28T10:20:06","slug":"mama-calendar","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/pt\/2026\/07\/28\/mama-calendar\/","title":{"rendered":"Mama Calendar &#8211; aplicativo de lembrete multiplataforma"},"content":{"rendered":"<p>Mama Calendar \u00e9 um aplicativo multiplataforma de eventos e lembretes escrito em React Native (Expo) com duas implementa\u00e7\u00f5es de backend: Node.js + MongoDB e PHP + MariaDB.<\/p>\n<p>O aplicativo permite criar eventos com categoriza\u00e7\u00e3o de emojis, selecionar o tipo de repeti\u00e7\u00e3o (uma vez, anualmente, mensalmente, semanalmente, diariamente) e visualizar eventos importantes dos pr\u00f3ximos 3 dias em uma aba separada \u201cEventos Importantes\u201d.<\/p>\n<h2>Pilha de tecnologia<\/h2>\n<p>O frontend \u00e9 escrito em React Native 0.86 via Expo SDK 57 com TypeScript, Expo Router para navega\u00e7\u00e3o e <code>react-native-reanimated<\/code> para anima\u00e7\u00f5es. Os s\u00edmbolos Expo s\u00e3o usados \u200b\u200bpara \u00edcones (s\u00edmbolos SF no iOS, \u00edcones de materiais no Android\/Web).<\/p>\n<p>O backend \u00e9 implementado em duas vers\u00f5es:<\/p>\n<ul>\n<li><b>Node.js:<\/b> Express 4, MongoDB 8 via driver nativo, autentica\u00e7\u00e3o personalizada com scrypt + salt, gerenciamento manual de tokens. Docker Compose traz o cliente (nginx), servidor e MongoDB.<\/li>\n<li><b>PHP:<\/b> PHP 8.2 sem frameworks, PDO + MariaDB 11, bcrypt para hash de senha, roteador pr\u00f3prio e carregamento autom\u00e1tico de PSR-4 via Composer.<\/li>\n<\/ul>\n<h2>Fun\u00e7\u00f5es do aplicativo<\/h2>\n<ul>\n<li><b>Registro e autoriza\u00e7\u00e3o:<\/b> sistema simples com nome de usu\u00e1rio\/senha e tokens ao portador<\/li>\n<li><b>Eventos CRUD:<\/b> crie, visualize, edite e exclua eventos com data, emoji e tipo de repeti\u00e7\u00e3o<\/li>\n<li><b>Filtragem inteligente:<\/b> A guia Eventos Importantes mostra os eventos dos pr\u00f3ximos 3 dias, levando em considera\u00e7\u00e3o as regras de repeti\u00e7\u00e3o. Por exemplo, eventos anuais mostram a ocorr\u00eancia anual mais pr\u00f3xima, mensalmente &#8211; por dia do m\u00eas, semanalmente &#8211; por dia da semana<\/li>\n<li><b>Seletor de emojis:<\/b> 20 emojis predefinidos para categoriza\u00e7\u00e3o r\u00e1pida de eventos<\/li>\n<li><b>Destacando os eventos de hoje:<\/b> os eventos de hoje s\u00e3o destacados com um fundo vermelho (#B71C1C)<\/li>\n<li><b>Tema escuro:<\/b> Detec\u00e7\u00e3o autom\u00e1tica do esquema de cores do sistema com paletas separadas para tema claro e escuro<\/li>\n<li><b>Internacionaliza\u00e7\u00e3o:<\/b> idiomas russo e ingl\u00eas via React Context<\/li>\n<li><b>\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u0438:<\/b> \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043b\u044d\u0448-\u0441\u043a\u0440\u0438\u043d \u0441 Keyframe API \u0438 \u0443\u043f\u0440\u0443\u0433\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u0435\u0439, \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0438\u043a\u043e\u043d\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u043c\u0441\u044f \u0441\u0432\u0435\u0447\u0435\u043d\u0438\u0435\u043c<\/li>\n<li><b>Endpoints administrativos:<\/b> gerenciamento de usu\u00e1rios, tokens e limpeza do banco de dados por meio de tokens mestres<\/li>\n<\/ul>\n<h2>Por que duas implementa\u00e7\u00f5es de back-end?<\/h2>\n<p>A vers\u00e3o Node.js \u00e9 a principal, mas a vers\u00e3o PHP existe como alternativa para uma hospedagem mais cl\u00e1ssica. A API \u00e9 completamente id\u00eantica, o que permite alternar entre elas sem alterar o c\u00f3digo do cliente.<\/p>\n<h2>Infraestrutura<\/h2>\n<p>Toda a pilha \u00e9 levantada atrav\u00e9s do Docker Compose: o cliente \u00e9 montado atrav\u00e9s de uma constru\u00e7\u00e3o multiest\u00e1gio (Expo export \u2192 nginx alpine), um servidor em Node.js, MongoDB 8. Para a vers\u00e3o PHP h\u00e1 um arquivo compose separado com MariaDB 11 e phpunit para testes.<\/p>\n<p>A montagem da vers\u00e3o web \u00e9 automatizada por um script PowerShell que corrige o API_URL antes da <code>expo export<\/code> e restaura os originais depois.<\/p>\n<h2>Sa\u00edda<\/h2>\n<p>Mama Calendar \u00e9 um aplicativo multiplataforma completo que cobre o ciclo completo: desde frontend m\u00f3vel e web no React Native at\u00e9 duas op\u00e7\u00f5es do lado do servidor. O projeto \u00e9 interessante por sua arquitetura, uso de recursos modernos do Expo SDK e implementa\u00e7\u00e3o de backend duplo.<\/p>\n<h2>Links<\/h2>\n<p><a href=\"https:\/\/github.com\/zefir1990\/Mama-Calendar\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/zefir1990\/Mama-Calendar<\/a><br \/>\n<a href=\"https:\/\/demensdeum.com\/software\/mama-calendar\/events\" rel=\"noopener\" target=\"_blank\">https:\/\/demensdeum.com\/software\/mama-calendar\/events<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mama Calendar \u00e9 um aplicativo multiplataforma de eventos e lembretes escrito em React Native (Expo) com duas implementa\u00e7\u00f5es de backend: Node.js + MongoDB e PHP + MariaDB. O aplicativo permite criar eventos com categoriza\u00e7\u00e3o de emojis, selecionar o tipo de repeti\u00e7\u00e3o (uma vez, anualmente, mensalmente, semanalmente, diariamente) e visualizar eventos importantes dos pr\u00f3ximos 3 dias [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-119","post","type-post","status-publish","format-standard","hentry","category-software"],"translation":{"provider":"WPGlobus","version":"3.0.3","language":"pt","enabled_languages":["en","ru","zh","de","ja","fr","es","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"es":{"title":false,"content":false,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":true,"content":true,"excerpt":false}}},"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/119","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=119"}],"version-history":[{"count":0,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/119\/revisions"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}