Branding & Customization
Replace the logo, launcher icons, colors, languages and fonts of the admin panel and both mobile apps with your own brand.
Change the app logo & icons
Each app has one master artwork, assets/logo.png. The in-app
brand mark and splash pick it up automatically; the platform launcher
icons and the native Android splash bitmap are separate files that you
regenerate after replacing the logo.
Replace assets/logo.png
Use a square, transparent PNG of at least 1024 px (the shipped
file is exactly 1024ร1024). No code changes are needed: the brand
mark lib/screens/common/app_mark.dart
(CargoAppMark) renders assets/logo.png
on the splash, onboarding, login and offline screens, and
lib/screens/auth/login_screen.dart references it
directly.
Regenerate the Android icons
Launcher icons under
android/app/src/main/res/mipmap-*/ic_launcher.png
and the native splash bitmap
mipmap-*/launch_image.png (centered by
drawable/launch_background.xml and
drawable-v21/launch_background.xml):
| Density folder | ic_launcher.png | launch_image.png |
|---|---|---|
mipmap-mdpi | 48ร48 | 160ร160 |
mipmap-hdpi | 72ร72 | 240ร240 |
mipmap-xhdpi | 96ร96 | 320ร320 |
mipmap-xxhdpi | 144ร144 | 480ร480 |
mipmap-xxxhdpi | 192ร192 | 640ร640 |
Regenerate the iOS icons
In ios/Runner/Assets.xcassets/AppIcon.appiconset/,
replace every Icon-App-*.png at the pixel size its
Contents.json entry declares (for example
Icon-App-40x40@2x.png is 80ร80,
Icon-App-1024x1024@1x.png is 1024ร1024). The splash
set LaunchImage.imageset holds
LaunchImage.png (480ร480), @2x (960ร960)
and @3x (1440ร1440).
Regenerate the web & Windows icons (user app only)
Web: web/favicon.png (64ร64) plus
web/icons/Icon-192.png, Icon-512.png and
the two Icon-maskable-*.png files referenced by
web/manifest.json. Windows desktop:
windows/runner/resources/app_icon.ico.
Or run the script below
Save it as regen_icons.py in the app folder
(cargoproapp/) and run it once โ it square-pads the
logo and writes every file listed above at the exact size.
pip install Pillow python regen_icons.py
Replace assets/logo.png
Same rule: a square, transparent PNG of at least 1024 px. The
login screen lib/screens/login_screen.dart renders
assets/logo.png directly, so it updates without any
code change.
Regenerate the Android icons
Identical layout to the user app:
android/app/src/main/res/mipmap-*/ic_launcher.png
at 48/72/96/144/192 px and
mipmap-*/launch_image.png at
160/240/320/480/640 px for the native splash
(drawable/launch_background.xml and
drawable-v21/launch_background.xml center it).
Regenerate the iOS & web icons
iOS: replace the Icon-App-*.png files in
ios/Runner/Assets.xcassets/AppIcon.appiconset/ per
its Contents.json, and
LaunchImage.png / @2x /
@3x in LaunchImage.imageset. Web:
web/favicon.png (64ร64) and
web/icons/Icon-192.png, Icon-512.png
plus the maskable variants. The driver app has no Windows
target, so there is no .ico to update.
Or run the script below
Save it as regen_icons.py in
cargoprodriver/ and run it โ the Windows step is
skipped automatically because the folder does not exist.
pip install Pillow python regen_icons.py
The icon regeneration script
One script covers both apps โ it square-pads
assets/logo.png, resizes it and saves every launcher,
splash and favicon file at its exact path and size. iOS icon sizes are
read straight from Contents.json, so the script stays
correct even if the asset catalog changes.
# regen_icons.py -- regenerate all app icons from assets/logo.png.
# Run from inside the app folder (cargoproapp/ or cargoprodriver/):
# pip install Pillow
# python regen_icons.py
import json
import os
from PIL import Image
APP = os.path.abspath(os.path.dirname(__file__))
logo = Image.open(os.path.join(APP, "assets", "logo.png")).convert("RGBA")
# Square-pad: center the artwork on a transparent square canvas.
side = max(logo.size)
mark = Image.new("RGBA", (side, side), (0, 0, 0, 0))
mark.paste(logo, ((side - logo.width) // 2, (side - logo.height) // 2), logo)
def save(size, rel):
path = os.path.join(APP, rel)
os.makedirs(os.path.dirname(path), exist_ok=True)
mark.resize((size, size), Image.LANCZOS).save(path)
# Android launcher icons + native splash bitmap.
DENSITIES = { # density: (ic_launcher px, launch_image px)
"mdpi": (48, 160), "hdpi": (72, 240), "xhdpi": (96, 320),
"xxhdpi": (144, 480), "xxxhdpi": (192, 640),
}
for dpi, (launcher, splash) in DENSITIES.items():
base = "android/app/src/main/res/mipmap-" + dpi
save(launcher, base + "/ic_launcher.png")
save(splash, base + "/launch_image.png")
# iOS AppIcon set -- pixel sizes derived from Contents.json.
xc = "ios/Runner/Assets.xcassets/AppIcon.appiconset"
with open(os.path.join(APP, xc, "Contents.json"), encoding="utf-8") as fh:
for entry in json.load(fh)["images"]:
px = round(float(entry["size"].split("x")[0]) * int(entry["scale"].rstrip("x")))
save(px, xc + "/" + entry["filename"])
# iOS launch image (480 px at 1x, then 2x and 3x variants).
li = "ios/Runner/Assets.xcassets/LaunchImage.imageset"
for suffix, px in [("", 480), ("@2x", 960), ("@3x", 1440)]:
save(px, li + "/LaunchImage" + suffix + ".png")
# Web favicon + PWA icons from web/manifest.json.
save(64, "web/favicon.png")
for px in (192, 512):
save(px, "web/icons/Icon-%d.png" % px)
save(px, "web/icons/Icon-maskable-%d.png" % px)
# Windows desktop icon (user app only; skipped for the driver app).
if os.path.isdir(os.path.join(APP, "windows")):
mark.resize((256, 256), Image.LANCZOS).save(
os.path.join(APP, "windows/runner/resources/app_icon.ico"),
sizes=[(16, 16), (32, 32), (48, 48), (64, 64), (256, 256)])
print("Done -- all launcher, splash and favicon images regenerated.")Admin panel logo & name
The admin panel's logo, favicon and site name are uploaded in the admin panel itself โ no file editing or redeploy needed. The full walkthrough (including where the files are stored and their fallbacks) lives on Customize the Admin Panel → Logo & favicon; the storage mechanics are in Admin Tools → Logo & favicon.
Colors & theme
All three products share the brand green #00D084. Each
product defines it in exactly one place:
| Product | Where the colors live | Guide |
|---|---|---|
| User app | cargoproapp/lib/core/theme.dart โ CargoColors.light / CargoColors.dark | Customize the Flutter Apps → Brand colors |
| Driver app | cargoprodriver/lib/core/theme.dart โ same structure | Customize the Flutter Apps → Brand colors |
| Admin panel | cargoproadmin/resources/css/app.css โ the Tailwind @theme brand scale | Customize the Admin Panel → Colors |
The per-product pages show the exact code and the values to change.
Languages
English, Arabic and Spanish ship with the product. The admin panel and the user app use different translation systems.
Admin panel (en / ar / es)
Translations live in
cargoproadmin/resources/lang/en.json,
ar.json and es.json. Each file maps the
English source text to its translation (2,259 keys per locale), and
Blade templates look strings up with
__('Company / Site Name'). To change or add wording, edit
the JSON files โ keep the key exactly as the English text used in
code.
Each admin user switches language from the header's language menu
(English / Espaรฑol / ุงูุนุฑุจูุฉ). It calls
GET /locale/{locale}
(LocaleController::switch), which validates the locale
against LocalizationServiceProvider (supports
en, es, ar) and stores it in
the session as app_locale โ the choice is per session,
per browser.
User app (Flutter gen-l10n)
The user app compiles its strings with Flutter's gen-l10n
(configured in cargoproapp/l10n.yaml, output to
lib/l10n/gen/). Source of truth: 19 part files in
lib/l10n/parts/ (one per feature, e.g.
auth.json, ship.json, ui.json),
each holding the en/ar/es
values per key:
{
"prefix": "auth",
"strings": {
"authSignIn": { "en": "Sign in", "ar": "ุชุณุฌูู ุงูุฏุฎูู", "es": "Iniciar sesiรณn" }
}
}After editing any part file, regenerate from the
cargoproapp/ folder:
dart run tool/merge_l10n.dart # parts -> app_en.arb / app_ar.arb / app_es.arb flutter gen-l10n # ARB -> lib/l10n/gen/ AppLocalizations
The merge tool enforces unique, lowerCamelCase keys that start with
the file's prefix, and falls back to English (with a
warning) when an ar/es value is missing โ
unless the admin panel's own lang file already translates the exact
English string, in which case it seeds from there.
flowchart LR
A["lib/l10n/parts/*.json"] -->|"dart run tool/merge_l10n.dart"| B["app_en.arb, app_ar.arb, app_es.arb"]
B -->|"flutter gen-l10n"| C["AppLocalizations in lib/l10n/gen/"]
C -->|"SettingsProvider.locale"| D["App UI with RTL for Arabic"]
Inside the app, users pick the language under
Profile โ Settings โ Preferences โ Language.
SettingsProvider.setLanguageCode persists the choice in
SharedPreferences; the supported codes are defined in
kSupportedLanguageCodes in
lib/providers/settings_provider.dart. Arabic layouts flip
to RTL automatically โ MaterialApp is built with the
provider's locale and the global material/widgets/cupertino
localization delegates, so no extra wiring is needed.
lib/l10n/parts/ โ missing values silently fall back to
English; 2) the locale added in tool/merge_l10n.dart โ
both the locales list and the output map that writes the
app_<locale>.arb files are hard-coded to
en/ar/es; 3) the code added to
kSupportedLanguageCodes in
lib/providers/settings_provider.dart and to the
_languageNames map in
lib/screens/profile/settings_screen.dart; then run the
two commands above.
Fonts
Both apps ship Nunito as static weight files in
assets/fonts/ (Nunito-400.ttf through
Nunito-900.ttf, plus the OFL.txt license)
and register them in pubspec.yaml:
fonts:
- family: Nunito
fonts:
- asset: assets/fonts/Nunito-400.ttf
weight: 400
- asset: assets/fonts/Nunito-500.ttf
weight: 500
- asset: assets/fonts/Nunito-600.ttf
weight: 600
- asset: assets/fonts/Nunito-700.ttf
weight: 700
- asset: assets/fonts/Nunito-800.ttf
weight: 800
- asset: assets/fonts/Nunito-900.ttf
weight: 900The fastest way to swap the typeface is to keep the
Nunito family name and overwrite the six
.ttf files with your font's weights (400โ900) โ the
themes (fontFamily: 'Nunito' in
AppTheme/DriverTheme) keep working. To use a
real new family name instead, update the family: line in
both apps' pubspec.yaml, the file names, and the
fontFamily references in
lib/core/theme.dart.
Outfit from Google Fonts in
resources/views/layouts/admin.blade.php; the stack is
defined by the --font-sans token in
resources/css/app.css. Swap the Google Fonts
<link> and the token together, then
npm run build.
Rename the application id / bundle id
The shipped Android ids are com.devtrixx.cargouser and
com.devtrixx.cargodriver (iOS bundle ids match). If you
publish under your own brand, rename them before registering the
apps in Firebase โ the package name is locked on first registration.
The step-by-step walkthrough (Gradle, Kotlin package, iOS project) is
now part of Customize the
Flutter Apps → Application ID.