diff --git a/.vscode/launch.json b/.vscode/launch.json
index 01d85e8..36ab075 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -3,7 +3,7 @@
"configurations": [
{
- "name": "ShoeInn API (uvicorn)",
+ "name": "Skruhb API (uvicorn)",
"type": "python",
"request": "launch",
"module": "uvicorn",
diff --git a/README.md b/README.md
index b4ac8b4..6cfc0dc 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,12 @@
-# ShoeInn
+
-Sneaker care scheduling, provider dispatch, notifications, and payment workflow demo.
+# Skruhb
+
+Operations software for cleaning and care businesses, including booking, provider dispatch, notifications, and payment workflows.
+
+## Brand assets
+
+The approved concept 45 compact SK ligature is the product identity. Exact Figma source exports are preserved in `brand/source`; cleaned, editable production masters for the deep blue-green, white, black, symbol-only, and horizontal lockups live in `brand/svg`. Platform raster derivatives live with the applications that consume them.
This repository is a small monorepo. Run each app from its own folder:
@@ -121,7 +127,7 @@ Useful options:
- `-SkipInstall` to skip `pip install`
- `-PaymentMode mock` or `-PaymentMode service`
- `-PaymentServiceBaseUrl "http://localhost:8001"` for service payment mode
-- `-MobileRedirectBase "exp://:8081/--"` for Expo Go returns, or `shoeinn://app` for a dev build
+- `-MobileRedirectBase "exp://:8081/--"` for Expo Go returns, or `skruhb://app` for a dev build
- `-Port 8000` to override the API port
If `apps/api/.env` already exists, the scripts preserve existing payment settings unless you explicitly pass `-PaymentMode`, `-PaymentServiceBaseUrl`, or `-MobileRedirectBase`.
@@ -244,20 +250,20 @@ Invoke-RestMethod -Method Post "http://localhost:8000/dev/seed?reset=true&demo_m
Default demo logins all use `Password1!`:
-- Global admin: `admin@shoeinn.com`
-- Customer: `customer@shoeinn.com`
-- Pelham owner: `pelham.admin@shoeinn.com`
-- Pelham providers: `pelham.driver1@shoeinn.com`, `pelham.driver2@shoeinn.com`
-- Helena owner: `helena.admin@shoeinn.com`
-- Helena provider: `helena.driver@shoeinn.com`
-- Alabaster owner: `alabaster.admin@shoeinn.com`
-- Alabaster provider: `alabaster.driver@shoeinn.com`
+- Global admin: `admin@skruhb.com`
+- Customer: `customer@skruhb.com`
+- Pelham owner: `pelham.admin@skruhb.com`
+- Pelham providers: `pelham.driver1@skruhb.com`, `pelham.driver2@skruhb.com`
+- Helena owner: `helena.admin@skruhb.com`
+- Helena provider: `helena.driver@skruhb.com`
+- Alabaster owner: `alabaster.admin@skruhb.com`
+- Alabaster provider: `alabaster.driver@skruhb.com`
Mt. Juliet quick-demo logins use `Password123!`:
-- Customer: `customer.mtjuliet@shoeinn.demo`
-- Provider: `provider.mtjuliet@shoeinn.demo`
-- Company admin: `admin.mtjuliet@shoeinn.demo`
+- Customer: `customer.mtjuliet@skruhb.demo`
+- Provider: `provider.mtjuliet@skruhb.demo`
+- Company admin: `admin.mtjuliet@skruhb.demo`
The seed response also returns the current login list and generated company IDs.
@@ -313,7 +319,7 @@ $env:EXPO_PUBLIC_GOOGLE_MAPS_API_KEY="your-google-directions-api-key"
$env:EXPO_PUBLIC_MOBILE_REDIRECT_BASE="exp://:8081/--"
```
-Use `EXPO_PUBLIC_MOBILE_REDIRECT_BASE="shoeinn://app"` for a dev build or standalone app that supports the custom scheme.
+Use `EXPO_PUBLIC_MOBILE_REDIRECT_BASE="skruhb://app"` for a dev build or standalone app that supports the custom scheme.
## Optional Payment Service
@@ -346,7 +352,7 @@ Then set these API values in `apps/api/.env`:
```env
PAYMENT_MODE=service
PAYMENT_SERVICE_BASE_URL=http://localhost:8001
-PAYMENT_MOBILE_REDIRECT_BASE=shoeinn://app
+PAYMENT_MOBILE_REDIRECT_BASE=skruhb://app
```
For Expo Go return-flow testing, use an explicit Expo URL instead:
@@ -496,5 +502,5 @@ Example login:
```powershell
Invoke-RestMethod -Method Post "http://localhost:8000/auth/login" `
-ContentType "application/json" `
- -Body '{"email":"customer@shoeinn.com","password":"Password1!"}'
+ -Body '{"email":"customer@skruhb.com","password":"Password1!"}'
```
diff --git a/apps/api/.env.example b/apps/api/.env.example
index c808eab..b4d08cd 100644
--- a/apps/api/.env.example
+++ b/apps/api/.env.example
@@ -8,7 +8,7 @@ PAYMENT_MODE=mock
PAYMENT_SERVICE_BASE_URL=
# Stripe should redirect to the mobile/frontend experience, not the API host.
# Development/dev client example:
-# PAYMENT_MOBILE_REDIRECT_BASE=shoeinn://app
+# PAYMENT_MOBILE_REDIRECT_BASE=skruhb://app
# Expo Go example:
# PAYMENT_MOBILE_REDIRECT_BASE=exp://192.168.1.29:8081/--
PAYMENT_MOBILE_REDIRECT_BASE=
diff --git a/apps/api/.env.staging.example b/apps/api/.env.staging.example
index 95f8424..ec6fed8 100644
--- a/apps/api/.env.staging.example
+++ b/apps/api/.env.staging.example
@@ -39,10 +39,10 @@ PAYMENT_CHECKOUT_CANCEL_URL=https://api.your-domain.com/payments/return/cancel
# App return URL after the browser success/cancel page.
# For installed preview/dev builds, use your app scheme.
# For Expo Go local testing, this may be exp://:8081/--/payment-return
-PAYMENT_RETURN_APP_URL=shoeinn://payment-return
+PAYMENT_RETURN_APP_URL=skruhb://payment-return
# Legacy/optional redirect base. Keep blank unless existing code still reads it.
PAYMENT_MOBILE_REDIRECT_BASE=
# Demo/test seed routes are still available in staging v2.
-# Protect them at the deployment layer or add an explicit seed secret before external demos.
\ No newline at end of file
+# Protect them at the deployment layer or add an explicit seed secret before external demos.
diff --git a/apps/api/README.md b/apps/api/README.md
index a91f735..aa8d6de 100644
--- a/apps/api/README.md
+++ b/apps/api/README.md
@@ -1,4 +1,4 @@
-# ShoeInn API
+# Skruhb API
FastAPI backend for authentication, companies, premium care services, booking holds, appointments, provider/company operations, live updates, notifications, payment reconciliation, and demo seeding.
@@ -111,7 +111,7 @@ Example login:
```powershell
Invoke-RestMethod -Method Post "http://localhost:8000/auth/login" `
-ContentType "application/json" `
- -Body '{"email":"customer@shoeinn.com","password":"Password1!"}'
+ -Body '{"email":"customer@skruhb.com","password":"Password1!"}'
```
## Payment Modes
@@ -129,7 +129,7 @@ Use service mode only when `apps/payment` is running:
```env
PAYMENT_MODE=service
PAYMENT_SERVICE_BASE_URL=http://localhost:8001
-PAYMENT_MOBILE_REDIRECT_BASE=shoeinn://app
+PAYMENT_MOBILE_REDIRECT_BASE=skruhb://app
```
For Expo Go return-flow testing:
diff --git a/apps/api/app/core/brand.py b/apps/api/app/core/brand.py
index 8660245..6c139eb 100644
--- a/apps/api/app/core/brand.py
+++ b/apps/api/app/core/brand.py
@@ -1,2 +1,2 @@
-APP_NAME = "ShoeInn"
+APP_NAME = "Skruhb"
CARE_MARKETPLACE_POSITIONING = "Premium care, pickup, and delivery from trusted local teams."
diff --git a/apps/api/app/main.py b/apps/api/app/main.py
index dd21af5..d622d22 100644
--- a/apps/api/app/main.py
+++ b/apps/api/app/main.py
@@ -36,7 +36,7 @@
force=True, # <- IMPORTANT: overrides existing handlers/config
)
-app = FastAPI(title="ShoeInn API")
+app = FastAPI(title="Skruhb API")
static_dir = Path(__file__).resolve().parent / "static"
static_dir.mkdir(parents=True, exist_ok=True)
diff --git a/apps/api/app/routers/admin.py b/apps/api/app/routers/admin.py
index de2d5bb..47e5d61 100644
--- a/apps/api/app/routers/admin.py
+++ b/apps/api/app/routers/admin.py
@@ -62,8 +62,8 @@ def _create_demo_user(db: Session, *, email: str, role: str, full_name: str, pas
def _seed_demo_data(db: Session) -> dict[str, object]:
now = datetime.now(timezone.utc)
- company_one = Company(name="Downtown ShoeInn", city="San Francisco", state="CA")
- company_two = Company(name="Uptown ShoeInn", city="New York", state="NY")
+ company_one = Company(name="Downtown Skruhb", city="San Francisco", state="CA")
+ company_two = Company(name="Uptown Skruhb", city="New York", state="NY")
db.add_all([company_one, company_two])
db.flush()
diff --git a/apps/api/app/routers/dev_seed.py b/apps/api/app/routers/dev_seed.py
index af91321..596e960 100644
--- a/apps/api/app/routers/dev_seed.py
+++ b/apps/api/app/routers/dev_seed.py
@@ -141,7 +141,7 @@ class SeedMarket(TypedDict):
},
],
"customer": {
- "email": "customer@shoeinn.com",
+ "email": "customer@skruhb.com",
"role": "customer",
"full_name": "Jordan Demo Customer",
},
@@ -150,18 +150,18 @@ class SeedMarket(TypedDict):
{
"name": "Pelham Pickup & Press",
"admin": {
- "email": "pelham.admin@shoeinn.com",
+ "email": "pelham.admin@skruhb.com",
"role": "company_admin",
"full_name": "Pelham Owner Demo",
},
"providers": [
{
- "email": "pelham.driver1@shoeinn.com",
+ "email": "pelham.driver1@skruhb.com",
"role": "provider",
"full_name": "Mason Route Lead",
},
{
- "email": "pelham.driver2@shoeinn.com",
+ "email": "pelham.driver2@skruhb.com",
"role": "provider",
"full_name": "Ava Delivery Lead",
},
@@ -193,13 +193,13 @@ class SeedMarket(TypedDict):
{
"name": "Helena Shoe & Dry Care",
"admin": {
- "email": "helena.admin@shoeinn.com",
+ "email": "helena.admin@skruhb.com",
"role": "company_admin",
"full_name": "Helena Owner Demo",
},
"providers": [
{
- "email": "helena.driver@shoeinn.com",
+ "email": "helena.driver@skruhb.com",
"role": "provider",
"full_name": "Noah Helena Driver",
},
@@ -231,13 +231,13 @@ class SeedMarket(TypedDict):
{
"name": "Alabaster Clean Run",
"admin": {
- "email": "alabaster.admin@shoeinn.com",
+ "email": "alabaster.admin@skruhb.com",
"role": "company_admin",
"full_name": "Alabaster Owner Demo",
},
"providers": [
{
- "email": "alabaster.driver@shoeinn.com",
+ "email": "alabaster.driver@skruhb.com",
"role": "provider",
"full_name": "Liam Alabaster Driver",
},
@@ -343,23 +343,23 @@ class SeedMarket(TypedDict):
},
],
"customer": {
- "email": "mtjuliet.customer@shoeinn.com",
+ "email": "mtjuliet.customer@skruhb.com",
"role": "customer",
"full_name": "Jordan Demo Customer",
},
"quick_demo_users": {
"customer": {
- "email": "customer.mtjuliet@shoeinn.demo",
+ "email": "customer.mtjuliet@skruhb.demo",
"role": "customer",
"full_name": "Avery Mt. Juliet Customer",
},
"provider": {
- "email": "provider.mtjuliet@shoeinn.demo",
+ "email": "provider.mtjuliet@skruhb.demo",
"role": "provider",
"full_name": "Cameron Mt. Juliet Provider",
},
"company_admin": {
- "email": "admin.mtjuliet@shoeinn.demo",
+ "email": "admin.mtjuliet@skruhb.demo",
"role": "company_admin",
"full_name": "Reese Mt. Juliet Company Admin",
},
@@ -368,18 +368,18 @@ class SeedMarket(TypedDict):
{
"name": "Mt. Juliet Pickup & Press",
"admin": {
- "email": "mtjuliet.admin@shoeinn.com",
+ "email": "mtjuliet.admin@skruhb.com",
"role": "company_admin",
"full_name": "Mt. Juliet Owner Demo",
},
"providers": [
{
- "email": "mtjuliet.driver1@shoeinn.com",
+ "email": "mtjuliet.driver1@skruhb.com",
"role": "provider",
"full_name": "Harper Route Lead",
},
{
- "email": "mtjuliet.driver2@shoeinn.com",
+ "email": "mtjuliet.driver2@skruhb.com",
"role": "provider",
"full_name": "Ethan Delivery Lead",
},
@@ -411,13 +411,13 @@ class SeedMarket(TypedDict):
{
"name": "Providence Shoe & Dry Care",
"admin": {
- "email": "providence.admin@shoeinn.com",
+ "email": "providence.admin@skruhb.com",
"role": "company_admin",
"full_name": "Providence Owner Demo",
},
"providers": [
{
- "email": "providence.driver@shoeinn.com",
+ "email": "providence.driver@skruhb.com",
"role": "provider",
"full_name": "Lucas Providence Driver",
},
@@ -449,13 +449,13 @@ class SeedMarket(TypedDict):
{
"name": "Golden Bear Clean Run",
"admin": {
- "email": "goldenbear.admin@shoeinn.com",
+ "email": "goldenbear.admin@skruhb.com",
"role": "company_admin",
"full_name": "Golden Bear Owner Demo",
},
"providers": [
{
- "email": "goldenbear.driver@shoeinn.com",
+ "email": "goldenbear.driver@skruhb.com",
"role": "provider",
"full_name": "Mia Golden Bear Driver",
},
@@ -505,7 +505,7 @@ def _all_demo_company_names() -> set[str]:
def _all_demo_emails() -> set[str]:
- emails = {"admin@shoeinn.com"}
+ emails = {"admin@skruhb.com"}
for demo_market in DEMO_MARKETS.values():
emails.add(demo_market["customer"]["email"])
emails.update(user["email"] for user in demo_market["quick_demo_users"].values())
@@ -739,7 +739,7 @@ def get_or_create_user(email: str, role: str, full_name: str, *, password: str =
created["users"] += 1
return user
- global_admin = get_or_create_user("admin@shoeinn.com", "admin", "ShoeInn Global Admin")
+ global_admin = get_or_create_user("admin@skruhb.com", "admin", "Skruhb Global Admin")
customer = get_or_create_user(
market["customer"]["email"],
market["customer"]["role"],
diff --git a/apps/api/app/routers/payment_return.py b/apps/api/app/routers/payment_return.py
index 2149971..d0adb0a 100644
--- a/apps/api/app/routers/payment_return.py
+++ b/apps/api/app/routers/payment_return.py
@@ -77,6 +77,13 @@ def _payment_return_page(*, title: str, body: str, app_url: str | None) -> HTMLR
padding: 32px 24px;
box-shadow: 0 20px 40px rgba(17, 24, 39, 0.08);
}}
+ .brand {{
+ display: block;
+ width: 190px;
+ max-width: 60%;
+ height: auto;
+ margin: 0 0 28px;
+ }}
h1 {{
margin: 0 0 12px;
font-size: 28px;
@@ -102,6 +109,7 @@ def _payment_return_page(*, title: str, body: str, app_url: str | None) -> HTMLR
+
{title}
{body}
{open_app_link}
diff --git a/apps/api/pyproject.toml b/apps/api/pyproject.toml
index 758ae4c..1f1bc79 100644
--- a/apps/api/pyproject.toml
+++ b/apps/api/pyproject.toml
@@ -1,5 +1,5 @@
[project]
-name = "shoeinn-api"
+name = "skruhb-api"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
diff --git a/apps/api/scripts/seed_services.py b/apps/api/scripts/seed_services.py
index fb87b79..23e6227 100644
--- a/apps/api/scripts/seed_services.py
+++ b/apps/api/scripts/seed_services.py
@@ -103,7 +103,7 @@ def seed_services(session: Session) -> int:
company = session.execute(select(Company).limit(1)).scalar_one_or_none()
if company is None:
- company = Company(name="ShoeInn", city="Anywhere", state="CA")
+ company = Company(name="Skruhb", city="Anywhere", state="CA")
session.add(company)
session.flush()
diff --git a/apps/api/tests/test_dev_seed.py b/apps/api/tests/test_dev_seed.py
index c1934d7..d5160d9 100644
--- a/apps/api/tests/test_dev_seed.py
+++ b/apps/api/tests/test_dev_seed.py
@@ -139,7 +139,7 @@ def test_dev_seed_populates_realistic_city_aligned_addresses(
assert response.status_code == 200, response.text
assert response.json()["demo_market"] == "shelby"
- customer = db_session.query(User).filter(User.email == "customer@shoeinn.com").one()
+ customer = db_session.query(User).filter(User.email == "customer@skruhb.com").one()
assert customer.address_line1 == "230 Tucker Road"
assert customer.address_line2 is None
assert customer.city == "Helena"
@@ -249,7 +249,7 @@ def test_dev_seed_mt_juliet_selector_resets_other_demo_markets_and_rotates_selec
).all()
assert default_companies == []
- customer = db_session.query(User).filter(User.email == "mtjuliet.customer@shoeinn.com").one()
+ customer = db_session.query(User).filter(User.email == "mtjuliet.customer@skruhb.com").one()
assert customer.address_line1 == "3005 Willow Bend Dr"
assert customer.address_line2 is None
assert customer.city == "Mt. Juliet"
@@ -325,14 +325,14 @@ def test_dev_seed_mt_juliet_quick_demo_users_have_expected_roles(
for user in db_session.query(User).filter(
User.email.in_(
[
- "customer.mtjuliet@shoeinn.demo",
- "provider.mtjuliet@shoeinn.demo",
- "admin.mtjuliet@shoeinn.demo",
+ "customer.mtjuliet@skruhb.demo",
+ "provider.mtjuliet@skruhb.demo",
+ "admin.mtjuliet@skruhb.demo",
]
)
)
}
- assert users["customer.mtjuliet@shoeinn.demo"].role == "customer"
- assert users["provider.mtjuliet@shoeinn.demo"].role == "provider"
- assert users["admin.mtjuliet@shoeinn.demo"].role == "company_admin"
+ assert users["customer.mtjuliet@skruhb.demo"].role == "customer"
+ assert users["provider.mtjuliet@skruhb.demo"].role == "provider"
+ assert users["admin.mtjuliet@skruhb.demo"].role == "company_admin"
diff --git a/apps/api/tests/test_payment_gateway.py b/apps/api/tests/test_payment_gateway.py
index a8018dd..ee9e9a5 100644
--- a/apps/api/tests/test_payment_gateway.py
+++ b/apps/api/tests/test_payment_gateway.py
@@ -67,7 +67,7 @@ def test_service_mode_requires_real_return_urls(
def test_service_mode_succeeds_with_valid_return_urls(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(settings, "payment_mode", "service")
monkeypatch.setattr(settings, "payment_service_base_url", "http://payments.test")
- monkeypatch.setattr(settings, "payment_mobile_redirect_base", "shoeinn://app")
+ monkeypatch.setattr(settings, "payment_mobile_redirect_base", "skruhb://app")
captured_payload: dict[str, object] = {}
@@ -103,7 +103,7 @@ def _handler(request: httpx.Request) -> httpx.Response:
cancel_url = str(captured_payload["cancel_url"])
success_parts = urlparse(success_url)
cancel_parts = urlparse(cancel_url)
- assert success_parts.scheme == "shoeinn"
+ assert success_parts.scheme == "skruhb"
assert success_parts.netloc == "app"
assert success_parts.path == "/payment/success"
assert cancel_parts.path == "/payment/cancel"
diff --git a/apps/api/tests/test_payment_return.py b/apps/api/tests/test_payment_return.py
index 45accb6..e56b7fa 100644
--- a/apps/api/tests/test_payment_return.py
+++ b/apps/api/tests/test_payment_return.py
@@ -10,14 +10,16 @@ def test_payment_return_success_page_includes_app_link(
client: TestClient,
monkeypatch: pytest.MonkeyPatch,
) -> None:
- monkeypatch.setattr(settings, "payment_mobile_redirect_base", "shoeinn://app")
+ monkeypatch.setattr(settings, "payment_mobile_redirect_base", "skruhb://app")
response = client.get("/payment/return/success?booking_id=booking-123&session_id=cs_123")
assert response.status_code == 200
body = response.text
assert "Payment received" in body
- assert "shoeinn://app/payment/success?booking_id=booking-123&session_id=cs_123" in body
- assert "Open ShoeInn" in body
+ assert "skruhb://app/payment/success?booking_id=booking-123&session_id=cs_123" in body
+ assert "Open Skruhb" in body
+ assert 'src="/static/skruhb-logo-deep.svg"' in body
+ assert 'alt="Skruhb"' in body
def test_payment_return_cancel_page_without_app_link_shows_manual_fallback(
@@ -30,5 +32,5 @@ def test_payment_return_cancel_page_without_app_link_shows_manual_fallback(
assert response.status_code == 200
body = response.text
assert "Checkout canceled" in body
- assert "Return to ShoeInn manually" in body
- assert "Open ShoeInn" not in body
+ assert "Return to Skruhb manually" in body
+ assert "Open Skruhb" not in body
diff --git a/apps/api/tests/test_services.py b/apps/api/tests/test_services.py
index 4ac205b..2563724 100644
--- a/apps/api/tests/test_services.py
+++ b/apps/api/tests/test_services.py
@@ -182,7 +182,7 @@ def test_company_services_can_filter_by_category(client: TestClient, db_session:
def test_seed_services_backfills_existing_uncategorized_services(db_session: Session) -> None:
- company = Company(name="Legacy ShoeInn", city="Mt. Juliet", state="TN")
+ company = Company(name="Legacy Skruhb", city="Mt. Juliet", state="TN")
db_session.add(company)
db_session.flush()
service = Service(
diff --git a/apps/mobile/.env.staging b/apps/mobile/.env.staging
index 03c12c1..577281a 100644
--- a/apps/mobile/.env.staging
+++ b/apps/mobile/.env.staging
@@ -1,4 +1,4 @@
-EXPO_PUBLIC_API_URL=https://api-shoeinn.mrwrite.dev
+EXPO_PUBLIC_API_URL=https://api.skruhb.com
EXPO_PUBLIC_APP_ENV=staging
EXPO_PUBLIC_ENABLE_DEMO_LOGINS=true
-EXPO_PUBLIC_GOOGLE_MAPS_API_KEY=
+EXPO_PUBLIC_GOOGLE_MAPS_API_KEY=AIzaSyBuGdJpuCV5rmcJQ_Hrg7Zkd0ajL6XUglw
\ No newline at end of file
diff --git a/apps/mobile/.env.staging.example b/apps/mobile/.env.staging.example
index 2af8a1d..bd5b7dd 100644
--- a/apps/mobile/.env.staging.example
+++ b/apps/mobile/.env.staging.example
@@ -6,7 +6,7 @@ EXPO_PUBLIC_API_BASE_URL=https://api-staging.example.com
EXPO_PUBLIC_APP_ENV=staging
EXPO_PUBLIC_ENABLE_DEMO_LOGINS=true
EXPO_PUBLIC_DEMO_MARKET=shelby
-EXPO_PUBLIC_MOBILE_REDIRECT_BASE=shoeinn://payment-return
+EXPO_PUBLIC_MOBILE_REDIRECT_BASE=skruhb://payment-return
# Optional for travel-route rendering in staging.
EXPO_PUBLIC_GOOGLE_MAPS_API_KEY=replace-me-for-staging
diff --git a/apps/mobile/README.md b/apps/mobile/README.md
index 8bef8cd..3a2fab6 100644
--- a/apps/mobile/README.md
+++ b/apps/mobile/README.md
@@ -1,7 +1,11 @@
-# ShoeInn Mobile
+
+
+# Skruhb Mobile
Expo React Native app for customer booking, provider job handling, company admin operations, live appointment updates, notifications, maps, and payment return flows.
+The reusable `Logo` component in `src/components/branding/Logo.tsx` renders the approved compact SK ligature and horizontal wordmark. Editable SVG masters and required Expo raster assets are stored in `assets/brand` and `assets` respectively.
+
## Requirements
- Node.js 20 LTS recommended
@@ -88,15 +92,15 @@ EXPO_PUBLIC_DEMO_MARKET=mt_juliet
Shelby County demo accounts use `Password1!`:
-- Customer: `customer@shoeinn.com`
-- Provider: `pelham.driver1@shoeinn.com`
-- Company admin: `pelham.admin@shoeinn.com`
+- Customer: `customer@skruhb.com`
+- Provider: `pelham.driver1@skruhb.com`
+- Company admin: `pelham.admin@skruhb.com`
Mt. Juliet demo accounts use `Password123!`:
-- Customer: `customer.mtjuliet@shoeinn.demo`
-- Provider: `provider.mtjuliet@shoeinn.demo`
-- Company admin: `admin.mtjuliet@shoeinn.demo`
+- Customer: `customer.mtjuliet@skruhb.demo`
+- Provider: `provider.mtjuliet@skruhb.demo`
+- Company admin: `admin.mtjuliet@skruhb.demo`
Seed data from the API before logging in:
@@ -125,7 +129,7 @@ For mock payment mode, no Stripe redirect setup is required.
For service payment mode with Stripe Checkout, configure the app return base:
```bash
-EXPO_PUBLIC_MOBILE_REDIRECT_BASE=shoeinn://app
+EXPO_PUBLIC_MOBILE_REDIRECT_BASE=skruhb://app
```
For Expo Go return-flow testing:
diff --git a/apps/mobile/app.config.ts b/apps/mobile/app.config.ts
index d8e3368..a5bb35e 100644
--- a/apps/mobile/app.config.ts
+++ b/apps/mobile/app.config.ts
@@ -15,17 +15,27 @@ const demoMarket = process.env.EXPO_PUBLIC_DEMO_MARKET ?? "shelby";
export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
- name: "Shoeinn",
- slug: "shoeinn",
- scheme: "shoeinn",
+ name: "Skruhb",
+ slug: "skruhb",
+ scheme: "skruhb",
version: "1.0.1",
+ icon: "./assets/icon.png",
userInterfaceStyle: "light",
orientation: "portrait",
platforms: ["ios", "android", "web"],
+ splash: {
+ image: "./assets/splash-icon.png",
+ resizeMode: "contain",
+ backgroundColor: "#F7F3EA",
+ },
android: {
...config.android,
- package: "com.mrwrite.shoeinn",
+ package: "com.mrwrite.skruhb",
versionCode: 2,
+ adaptiveIcon: {
+ foregroundImage: "./assets/adaptive-icon.png",
+ backgroundColor: "#062E37",
+ },
config: {
...config.android?.config,
googleMaps: {
@@ -35,7 +45,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
},
ios: {
...config.ios,
- bundleIdentifier: "com.mrwrite.shoeinn",
+ bundleIdentifier: "com.mrwrite.skruhb",
config: {
...config.ios?.config,
googleMapsApiKey: process.env.EXPO_PUBLIC_GOOGLE_MAPS_API_KEY,
@@ -44,6 +54,10 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
ITSAppUsesNonExemptEncryption: false,
},
},
+ web: {
+ ...config.web,
+ favicon: "./assets/favicon.png",
+ },
updates: {
...config.updates,
checkAutomatically: "ON_ERROR_RECOVERY",
diff --git a/apps/mobile/app.json.bak b/apps/mobile/app.json.bak
index 7f150f6..3964f4f 100644
--- a/apps/mobile/app.json.bak
+++ b/apps/mobile/app.json.bak
@@ -1,9 +1,24 @@
{
"expo": {
- "name": "shoeinn",
- "slug": "shoeinn",
+ "name": "Skruhb",
+ "slug": "skruhb",
"version": "1.0.0",
"orientation": "portrait",
+ "icon": "./assets/icon.png",
+ "splash": {
+ "image": "./assets/splash-icon.png",
+ "resizeMode": "contain",
+ "backgroundColor": "#F7F3EA"
+ },
+ "android": {
+ "adaptiveIcon": {
+ "foregroundImage": "./assets/adaptive-icon.png",
+ "backgroundColor": "#062E37"
+ }
+ },
+ "web": {
+ "favicon": "./assets/favicon.png"
+ },
"platforms": [
"ios",
"android",
diff --git a/apps/mobile/assets/adaptive-icon.png b/apps/mobile/assets/adaptive-icon.png
new file mode 100644
index 0000000..3d2c1b4
Binary files /dev/null and b/apps/mobile/assets/adaptive-icon.png differ
diff --git a/apps/mobile/assets/brand/skruhb-app-icon.svg b/apps/mobile/assets/brand/skruhb-app-icon.svg
new file mode 100644
index 0000000..b79b91a
--- /dev/null
+++ b/apps/mobile/assets/brand/skruhb-app-icon.svg
@@ -0,0 +1,2 @@
+
diff --git a/apps/mobile/assets/brand/skruhb-logo-black.png b/apps/mobile/assets/brand/skruhb-logo-black.png
new file mode 100644
index 0000000..6a41f5b
Binary files /dev/null and b/apps/mobile/assets/brand/skruhb-logo-black.png differ
diff --git a/apps/mobile/assets/brand/skruhb-logo-black.svg b/apps/mobile/assets/brand/skruhb-logo-black.svg
new file mode 100644
index 0000000..4277aa7
--- /dev/null
+++ b/apps/mobile/assets/brand/skruhb-logo-black.svg
@@ -0,0 +1,2 @@
+
diff --git a/apps/mobile/assets/brand/skruhb-logo-deep.png b/apps/mobile/assets/brand/skruhb-logo-deep.png
new file mode 100644
index 0000000..cafdae7
Binary files /dev/null and b/apps/mobile/assets/brand/skruhb-logo-deep.png differ
diff --git a/apps/mobile/assets/brand/skruhb-logo-deep.svg b/apps/mobile/assets/brand/skruhb-logo-deep.svg
new file mode 100644
index 0000000..dca3c1e
--- /dev/null
+++ b/apps/mobile/assets/brand/skruhb-logo-deep.svg
@@ -0,0 +1,2 @@
+
diff --git a/apps/mobile/assets/brand/skruhb-logo-white.png b/apps/mobile/assets/brand/skruhb-logo-white.png
new file mode 100644
index 0000000..6bd5228
Binary files /dev/null and b/apps/mobile/assets/brand/skruhb-logo-white.png differ
diff --git a/apps/mobile/assets/brand/skruhb-logo-white.svg b/apps/mobile/assets/brand/skruhb-logo-white.svg
new file mode 100644
index 0000000..c6a42e5
--- /dev/null
+++ b/apps/mobile/assets/brand/skruhb-logo-white.svg
@@ -0,0 +1,2 @@
+
diff --git a/apps/mobile/assets/brand/skruhb-symbol-black.png b/apps/mobile/assets/brand/skruhb-symbol-black.png
new file mode 100644
index 0000000..51f6349
Binary files /dev/null and b/apps/mobile/assets/brand/skruhb-symbol-black.png differ
diff --git a/apps/mobile/assets/brand/skruhb-symbol-black.svg b/apps/mobile/assets/brand/skruhb-symbol-black.svg
new file mode 100644
index 0000000..d762896
--- /dev/null
+++ b/apps/mobile/assets/brand/skruhb-symbol-black.svg
@@ -0,0 +1,2 @@
+
diff --git a/apps/mobile/assets/brand/skruhb-symbol-brand.png b/apps/mobile/assets/brand/skruhb-symbol-brand.png
new file mode 100644
index 0000000..960f090
Binary files /dev/null and b/apps/mobile/assets/brand/skruhb-symbol-brand.png differ
diff --git a/apps/mobile/assets/brand/skruhb-symbol-brand.svg b/apps/mobile/assets/brand/skruhb-symbol-brand.svg
new file mode 100644
index 0000000..fe73189
--- /dev/null
+++ b/apps/mobile/assets/brand/skruhb-symbol-brand.svg
@@ -0,0 +1,2 @@
+
diff --git a/apps/mobile/assets/brand/skruhb-symbol-white.png b/apps/mobile/assets/brand/skruhb-symbol-white.png
new file mode 100644
index 0000000..cac0488
Binary files /dev/null and b/apps/mobile/assets/brand/skruhb-symbol-white.png differ
diff --git a/apps/mobile/assets/brand/skruhb-symbol-white.svg b/apps/mobile/assets/brand/skruhb-symbol-white.svg
new file mode 100644
index 0000000..948146f
--- /dev/null
+++ b/apps/mobile/assets/brand/skruhb-symbol-white.svg
@@ -0,0 +1,2 @@
+
diff --git a/apps/mobile/assets/favicon.png b/apps/mobile/assets/favicon.png
new file mode 100644
index 0000000..1834983
Binary files /dev/null and b/apps/mobile/assets/favicon.png differ
diff --git a/apps/mobile/assets/icon.png b/apps/mobile/assets/icon.png
new file mode 100644
index 0000000..efa83b1
Binary files /dev/null and b/apps/mobile/assets/icon.png differ
diff --git a/apps/mobile/assets/splash-icon.png b/apps/mobile/assets/splash-icon.png
new file mode 100644
index 0000000..ba7b8de
Binary files /dev/null and b/apps/mobile/assets/splash-icon.png differ
diff --git a/apps/mobile/eas.json b/apps/mobile/eas.json
index 72f25d8..d508c80 100644
--- a/apps/mobile/eas.json
+++ b/apps/mobile/eas.json
@@ -7,7 +7,7 @@
"developmentClient": true,
"distribution": "internal",
"env": {
- "EXPO_PUBLIC_API_URL": "https://api-shoeinn.mrwrite.dev",
+ "EXPO_PUBLIC_API_URL": "https://api.skruhb.com",
"EXPO_PUBLIC_APP_ENV": "staging",
"EXPO_PUBLIC_ENABLE_DEMO_LOGINS": "true"
}
@@ -18,17 +18,17 @@
"buildType": "apk"
},
"env": {
- "EXPO_PUBLIC_API_URL": "https://api-shoeinn.mrwrite.dev",
+ "EXPO_PUBLIC_API_URL": "https://api.skruhb.com",
"EXPO_PUBLIC_APP_ENV": "staging",
"EXPO_PUBLIC_ENABLE_DEMO_LOGINS": "true",
"EXPO_PUBLIC_GOOGLE_MAPS_API_KEY": "AIzaSyBuGdJpuCV5rmcJQ_Hrg7Zkd0ajL6XUglw",
- "EXPO_PUBLIC_MOBILE_REDIRECT_BASE": "shoeinn://payment-return",
+ "EXPO_PUBLIC_MOBILE_REDIRECT_BASE": "skruhb://payment-return",
"EXPO_PUBLIC_DEMO_MARKET": "shelby"
}
},
"production": {
"env": {
- "EXPO_PUBLIC_API_URL": "https://api-shoeinn.mrwrite.dev",
+ "EXPO_PUBLIC_API_URL": "https://api.skruhb.com",
"EXPO_PUBLIC_APP_ENV": "production",
"EXPO_PUBLIC_ENABLE_DEMO_LOGINS": "false"
}
diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json
index f4de58e..2287aa8 100644
--- a/apps/mobile/package-lock.json
+++ b/apps/mobile/package-lock.json
@@ -1,11 +1,11 @@
{
- "name": "shoeinn-mobile",
+ "name": "skruhb-mobile",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "shoeinn-mobile",
+ "name": "skruhb-mobile",
"version": "1.0.0",
"dependencies": {
"@expo/metro-runtime": "~6.1.2",
diff --git a/apps/mobile/package.json b/apps/mobile/package.json
index fe91ed2..9bce047 100644
--- a/apps/mobile/package.json
+++ b/apps/mobile/package.json
@@ -1,5 +1,5 @@
{
- "name": "shoeinn-mobile",
+ "name": "skruhb-mobile",
"version": "1.0.0",
"private": true,
"main": "index.js",
diff --git a/apps/mobile/src/__tests__/demoLogins.test.ts b/apps/mobile/src/__tests__/demoLogins.test.ts
index cf2fbf5..0d66a5b 100644
--- a/apps/mobile/src/__tests__/demoLogins.test.ts
+++ b/apps/mobile/src/__tests__/demoLogins.test.ts
@@ -28,17 +28,17 @@ describe("demo login helpers", () => {
expect(getDemoLoginAccounts("shelby")).toEqual([
{
label: "Shelby Customer",
- email: "customer@shoeinn.com",
+ email: "customer@skruhb.com",
password: "Password1!",
},
{
label: "Shelby Provider",
- email: "pelham.driver1@shoeinn.com",
+ email: "pelham.driver1@skruhb.com",
password: "Password1!",
},
{
label: "Shelby Company Admin",
- email: "pelham.admin@shoeinn.com",
+ email: "pelham.admin@skruhb.com",
password: "Password1!",
},
]);
@@ -56,17 +56,17 @@ describe("demo login helpers", () => {
expect(getDemoLoginAccounts("mt_juliet")).toEqual([
{
label: "Mt. Juliet Customer",
- email: "customer.mtjuliet@shoeinn.demo",
+ email: "customer.mtjuliet@skruhb.demo",
password: "Password123!",
},
{
label: "Mt. Juliet Provider",
- email: "provider.mtjuliet@shoeinn.demo",
+ email: "provider.mtjuliet@skruhb.demo",
password: "Password123!",
},
{
label: "Mt. Juliet Company Admin",
- email: "admin.mtjuliet@shoeinn.demo",
+ email: "admin.mtjuliet@skruhb.demo",
password: "Password123!",
},
]);
diff --git a/apps/mobile/src/__tests__/servicesCache.test.ts b/apps/mobile/src/__tests__/servicesCache.test.ts
index 79518b4..9fb9f45 100644
--- a/apps/mobile/src/__tests__/servicesCache.test.ts
+++ b/apps/mobile/src/__tests__/servicesCache.test.ts
@@ -16,7 +16,7 @@ describe('services cache hydration', () => {
duration_min: 30,
company: {
id: 'company-1',
- name: 'Shoe Inn',
+ name: 'Skruhb',
city: 'Seattle',
state: 'WA',
},
diff --git a/apps/mobile/src/auth/demoLogins.ts b/apps/mobile/src/auth/demoLogins.ts
index 50eba41..7e6b11f 100644
--- a/apps/mobile/src/auth/demoLogins.ts
+++ b/apps/mobile/src/auth/demoLogins.ts
@@ -15,17 +15,17 @@ export type DemoMarketDiscoveryLocation = {
export const SHELBY_DEMO_ACCOUNTS: DemoLoginAccount[] = [
{
label: "Shelby Customer",
- email: "customer@shoeinn.com",
+ email: "customer@skruhb.com",
password: "Password1!",
},
{
label: "Shelby Provider",
- email: "pelham.driver1@shoeinn.com",
+ email: "pelham.driver1@skruhb.com",
password: "Password1!",
},
{
label: "Shelby Company Admin",
- email: "pelham.admin@shoeinn.com",
+ email: "pelham.admin@skruhb.com",
password: "Password1!",
},
];
@@ -33,17 +33,17 @@ export const SHELBY_DEMO_ACCOUNTS: DemoLoginAccount[] = [
export const MT_JULIET_DEMO_ACCOUNTS: DemoLoginAccount[] = [
{
label: "Mt. Juliet Customer",
- email: "customer.mtjuliet@shoeinn.demo",
+ email: "customer.mtjuliet@skruhb.demo",
password: "Password123!",
},
{
label: "Mt. Juliet Provider",
- email: "provider.mtjuliet@shoeinn.demo",
+ email: "provider.mtjuliet@skruhb.demo",
password: "Password123!",
},
{
label: "Mt. Juliet Company Admin",
- email: "admin.mtjuliet@shoeinn.demo",
+ email: "admin.mtjuliet@skruhb.demo",
password: "Password123!",
},
];
diff --git a/apps/mobile/src/components/AppHeader.tsx b/apps/mobile/src/components/AppHeader.tsx
index 57cf90d..e998c1f 100644
--- a/apps/mobile/src/components/AppHeader.tsx
+++ b/apps/mobile/src/components/AppHeader.tsx
@@ -4,6 +4,7 @@ import { Ionicons } from "@expo/vector-icons";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useTheme } from "../theme/theme";
+import { Logo } from "./branding/Logo";
interface AppHeaderProps {
title?: string;
@@ -19,7 +20,7 @@ export function AppHeader({ title, locationLabel, onPressLocation, onPressNotifi
return (
- {title ?? "Explore"}
+ {title === "Skruhb" ? : {title ?? "Explore"}}
{locationLabel}
diff --git a/apps/mobile/src/components/branding/Logo.test.tsx b/apps/mobile/src/components/branding/Logo.test.tsx
new file mode 100644
index 0000000..a6079e8
--- /dev/null
+++ b/apps/mobile/src/components/branding/Logo.test.tsx
@@ -0,0 +1,25 @@
+import React from "react";
+// @ts-expect-error The current Jest renderer dependency does not ship TypeScript declarations.
+import renderer, { act } from "react-test-renderer";
+
+import { Logo } from "./Logo";
+
+describe("Logo", () => {
+ it("exposes one useful accessible brand name", () => {
+ let tree: any;
+ act(() => {
+ tree = renderer.create();
+ });
+
+ expect(tree!.root.findByProps({ accessibilityLabel: "Skruhb" })).toBeTruthy();
+ });
+
+ it("can be marked decorative", () => {
+ let tree: any;
+ act(() => {
+ tree = renderer.create();
+ });
+
+ expect(tree!.root.findByProps({ importantForAccessibility: "no" })).toBeTruthy();
+ });
+});
diff --git a/apps/mobile/src/components/branding/Logo.tsx b/apps/mobile/src/components/branding/Logo.tsx
new file mode 100644
index 0000000..6f14b43
--- /dev/null
+++ b/apps/mobile/src/components/branding/Logo.tsx
@@ -0,0 +1,51 @@
+import React from "react";
+import { Image, type ImageSourcePropType, type ImageStyle, type StyleProp } from "react-native";
+
+export type LogoLayout = "horizontal" | "symbol";
+export type LogoTone = "brand" | "light" | "black";
+
+interface LogoProps {
+ layout?: LogoLayout;
+ tone?: LogoTone;
+ size?: number;
+ decorative?: boolean;
+ style?: StyleProp;
+}
+
+const sources: Record> = {
+ horizontal: {
+ brand: require("../../../assets/brand/skruhb-logo-deep.png"),
+ light: require("../../../assets/brand/skruhb-logo-white.png"),
+ black: require("../../../assets/brand/skruhb-logo-black.png"),
+ },
+ symbol: {
+ brand: require("../../../assets/brand/skruhb-symbol-brand.png"),
+ light: require("../../../assets/brand/skruhb-symbol-white.png"),
+ black: require("../../../assets/brand/skruhb-symbol-black.png"),
+ },
+};
+
+const HORIZONTAL_ASPECT_RATIO = 345 / 140;
+
+export function Logo({
+ layout = "horizontal",
+ tone = "brand",
+ size = layout === "horizontal" ? 42 : 44,
+ decorative = false,
+ style,
+}: LogoProps) {
+ const width = layout === "horizontal" ? size * HORIZONTAL_ASPECT_RATIO : size;
+
+ return (
+
+ );
+}
+
+export default Logo;
diff --git a/apps/mobile/src/components/rewardsCard.test.tsx b/apps/mobile/src/components/rewardsCard.test.tsx
index 087c7c6..19eb7f8 100644
--- a/apps/mobile/src/components/rewardsCard.test.tsx
+++ b/apps/mobile/src/components/rewardsCard.test.tsx
@@ -19,12 +19,12 @@ describe("RewardsCard", () => {
act(() => {
tree = renderer.create(
- ,
+ ,
);
});
const output = JSON.stringify(tree?.toJSON());
- expect(output).toContain("ShoeInn Care Club");
+ expect(output).toContain("Skruhb Care Club");
expect(output).toContain("Premium care, pickup, and delivery");
expect(output).toContain("Member");
});
diff --git a/apps/mobile/src/components/ui/RewardsCard.tsx b/apps/mobile/src/components/ui/RewardsCard.tsx
index 52abf73..4a0b4d7 100644
--- a/apps/mobile/src/components/ui/RewardsCard.tsx
+++ b/apps/mobile/src/components/ui/RewardsCard.tsx
@@ -17,7 +17,7 @@ type RewardsCardProps = {
* content. It does not imply new backend rewards behavior.
*/
export function RewardsCard({
- title = "ShoeInn Care Club",
+ title = "Skruhb Care Club",
subtitle = "Premium care, pickup, and delivery",
value = "Member",
style,
diff --git a/apps/mobile/src/content/brandCopy.ts b/apps/mobile/src/content/brandCopy.ts
index 45546fd..47c6f55 100644
--- a/apps/mobile/src/content/brandCopy.ts
+++ b/apps/mobile/src/content/brandCopy.ts
@@ -1,5 +1,5 @@
export const brandCopy = {
- appName: "ShoeInn",
+ appName: "Skruhb",
marketplacePositioning: "Premium care, pickup, and delivery from trusted local teams.",
homeTitle: "Book premium care services",
homeSubtitle: "Browse trusted local care providers and schedule pickup in minutes.",
diff --git a/apps/mobile/src/discovery/categoryDiscovery.test.ts b/apps/mobile/src/discovery/categoryDiscovery.test.ts
index b726d24..721ce75 100644
--- a/apps/mobile/src/discovery/categoryDiscovery.test.ts
+++ b/apps/mobile/src/discovery/categoryDiscovery.test.ts
@@ -51,7 +51,7 @@ describe("category discovery helpers", () => {
const companies: Company[] = [
{
id: "company-shoes",
- name: "ShoeInn",
+ name: "Skruhb",
offered_categories: [{ id: "1", slug: "shoes", name: "Shoes", icon_key: "footprints" }],
},
{
diff --git a/apps/mobile/src/navigation/AuthGate.tsx b/apps/mobile/src/navigation/AuthGate.tsx
index d4efe51..5a4615b 100644
--- a/apps/mobile/src/navigation/AuthGate.tsx
+++ b/apps/mobile/src/navigation/AuthGate.tsx
@@ -1,11 +1,12 @@
import React, { useEffect } from "react";
-import { ActivityIndicator, Linking, View } from "react-native";
+import { ActivityIndicator, Linking, StyleSheet, View } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import AuthStack from "./AuthStack";
import AppStack from "./AppStack";
import { navigateWhenReady, navigationRef } from "./rootNavigation";
import { useAuthStore } from "../state/authStore";
+import { Logo } from "../components/branding/Logo";
function normalizeIncomingPath(pathname: string, host: string): string {
const trimmed = pathname.replace(/^\/+/, "");
@@ -77,9 +78,10 @@ export default function AuthGate() {
if (loading) {
return (
-
+
+
);
}
@@ -90,3 +92,13 @@ export default function AuthGate() {
);
}
+
+const styles = StyleSheet.create({
+ loading: {
+ flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ gap: 20,
+ backgroundColor: "#F7F3EA",
+ },
+});
diff --git a/apps/mobile/src/screens/CustomerInfoScreen.tsx b/apps/mobile/src/screens/CustomerInfoScreen.tsx
index 4d23845..d7be454 100644
--- a/apps/mobile/src/screens/CustomerInfoScreen.tsx
+++ b/apps/mobile/src/screens/CustomerInfoScreen.tsx
@@ -201,7 +201,7 @@ const CustomerInfoScreen: React.FC = ({ onConfirmed, onBack }) => {
Cancel unpaid booking
- After paying in Stripe Checkout, ShoeInn should reopen automatically when supported. If it does not, return to the app and check payment status.
+ After paying in Stripe Checkout, Skruhb should reopen automatically when supported. If it does not, return to the app and check payment status.
);
diff --git a/apps/mobile/src/screens/auth/LoginScreen.tsx b/apps/mobile/src/screens/auth/LoginScreen.tsx
index edd81b3..2442a0a 100644
--- a/apps/mobile/src/screens/auth/LoginScreen.tsx
+++ b/apps/mobile/src/screens/auth/LoginScreen.tsx
@@ -11,6 +11,7 @@ import { AppCard } from "../../components/AppCard";
import { AppScreen } from "../../components/AppScreen";
import { MediaPlaceholder } from "../../components/ui/MediaPlaceholder";
import { SectionHeader } from "../../components/SectionHeader";
+import { Logo } from "../../components/branding/Logo";
import { Text } from "../../components/ui/Text";
import { brandCopy } from "../../content/brandCopy";
import { AuthStackParamList } from "../../navigation/AuthStack";
@@ -24,7 +25,7 @@ export default function LoginScreen({ navigation }: Props) {
const setAuth = useAuthStore((s) => s.setAuth);
const rememberMe = useAuthStore((s) => s.rememberMe);
const setRememberMe = useAuthStore((s) => s.setRememberMe);
- const [email, setEmail] = useState("customer@shoeinn.com");
+ const [email, setEmail] = useState("customer@skruhb.com");
const [password, setPassword] = useState("Password1!");
const [error, setError] = useState(null);
const showDemoLogins = shouldShowDemoLogins();
@@ -50,9 +51,7 @@ export default function LoginScreen({ navigation }: Props) {
-
-
-
+
Premium care
@@ -60,9 +59,7 @@ export default function LoginScreen({ navigation }: Props) {
-
- {brandCopy.appName}
-
+
{brandCopy.marketplacePositioning}
@@ -79,7 +76,7 @@ export default function LoginScreen({ navigation }: Props) {
@@ -223,14 +220,6 @@ const styles = StyleSheet.create({
hero: {
gap: 8,
},
- logoMark: {
- width: 52,
- height: 52,
- borderRadius: 20,
- borderWidth: 1,
- alignItems: "center",
- justifyContent: "center",
- },
brandPill: {
minHeight: 32,
borderRadius: 999,
diff --git a/apps/mobile/src/screens/auth/RegisterScreen.tsx b/apps/mobile/src/screens/auth/RegisterScreen.tsx
index 69498e8..70594b3 100644
--- a/apps/mobile/src/screens/auth/RegisterScreen.tsx
+++ b/apps/mobile/src/screens/auth/RegisterScreen.tsx
@@ -15,6 +15,7 @@ import { useMutation } from "@tanstack/react-query";
import { SafeAreaView } from "react-native-safe-area-context";
import { login, register } from "../../api/http";
+import { Logo } from "../../components/branding/Logo";
import { AuthStackParamList } from "../../navigation/AuthStack";
import { useAuthStore } from "../../state/authStore";
@@ -50,8 +51,9 @@ export default function RegisterScreen({ navigation }: Props) {
style={styles.flex}
>
+
Create an account
- Start booking clean kicks
+ Run your care from one connected place
{error ? {error} : null}
@@ -107,8 +109,9 @@ export default function RegisterScreen({ navigation }: Props) {
const styles = StyleSheet.create({
flex: { flex: 1 },
- safeArea: { flex: 1, backgroundColor: "#f3f4f6" },
+ safeArea: { flex: 1, backgroundColor: "#F7F3EA" },
container: { padding: 24, gap: 12 },
+ logo: { marginBottom: 12 },
title: { fontSize: 28, fontWeight: "700", marginTop: 12 },
subtitle: { fontSize: 16, color: "#4b5563" },
field: { gap: 4 },
diff --git a/apps/mobile/src/screens/company/ProviderDashboardScreen.tsx b/apps/mobile/src/screens/company/ProviderDashboardScreen.tsx
index d8413ac..cf0c186 100644
--- a/apps/mobile/src/screens/company/ProviderDashboardScreen.tsx
+++ b/apps/mobile/src/screens/company/ProviderDashboardScreen.tsx
@@ -5,6 +5,7 @@ import { useQuery } from "@tanstack/react-query";
import { SafeAreaView } from "react-native-safe-area-context";
import { fetchOpenAppointments } from "../../api/http";
+import { Logo } from "../../components/branding/Logo";
import { CompanyStackParamList } from "../../navigation/CompanyStack";
import { useAuthStore } from "../../state/authStore";
import type { ProviderAppointment } from "../../types/company";
@@ -41,7 +42,10 @@ export default function ProviderDashboardScreen({ navigation }: Props) {
return (
- Provider dashboard
+
+
+ Provider dashboard
+
navigation.navigate("Notifications")} style={styles.linkButton}>
🔔
@@ -81,7 +85,8 @@ const styles = StyleSheet.create({
justifyContent: "space-between",
alignItems: "center",
},
- headerTitle: { fontSize: 20, fontWeight: "700" },
+ headerBrand: { gap: 2 },
+ headerSubtitle: { color: "#596568", fontSize: 12, fontWeight: "600" },
headerActions: { flexDirection: "row", alignItems: "center", columnGap: 12 },
linkButton: { paddingHorizontal: 6, paddingVertical: 4 },
linkText: { color: "#1d4ed8", fontWeight: "600", fontSize: 16 },
diff --git a/apps/mobile/src/screens/customer/AppointmentDetailScreen.tsx b/apps/mobile/src/screens/customer/AppointmentDetailScreen.tsx
index 2361fda..acca587 100644
--- a/apps/mobile/src/screens/customer/AppointmentDetailScreen.tsx
+++ b/apps/mobile/src/screens/customer/AppointmentDetailScreen.tsx
@@ -246,7 +246,7 @@ export default function AppointmentDetailScreen({ route }: Props) {
Alert.alert(
"Payment submitted",
- latest.payment_message ?? "We returned to ShoeInn, but Stripe has not marked this payment complete yet. You can refresh again if needed.",
+ latest.payment_message ?? "We returned to Skruhb, but Stripe has not marked this payment complete yet. You can refresh again if needed.",
);
} catch (error: any) {
Alert.alert("Unable to refresh payment", error?.message ?? "Please try again.");
diff --git a/apps/mobile/src/screens/customer/CustomerHomeScreen.tsx b/apps/mobile/src/screens/customer/CustomerHomeScreen.tsx
index 68c26f6..00eafe3 100644
--- a/apps/mobile/src/screens/customer/CustomerHomeScreen.tsx
+++ b/apps/mobile/src/screens/customer/CustomerHomeScreen.tsx
@@ -37,7 +37,7 @@ export default function CustomerHomeScreen() {
return (
-
+
diff --git a/apps/mobile/src/screens/home/BookingDateScreen.tsx b/apps/mobile/src/screens/home/BookingDateScreen.tsx
index da5d379..9037a6b 100644
--- a/apps/mobile/src/screens/home/BookingDateScreen.tsx
+++ b/apps/mobile/src/screens/home/BookingDateScreen.tsx
@@ -5,6 +5,7 @@ import { RouteProp, useNavigation, useRoute } from "@react-navigation/native";
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { AppScreen } from "../../components/ui/AppScreen";
+import { Logo } from "../../components/branding/Logo";
import { Button } from "../../components/ui/Button";
import { Card, PressableCard } from "../../components/ui/Card";
import { MediaPlaceholder } from "../../components/ui/MediaPlaceholder";
@@ -245,12 +246,7 @@ function BookingTopBar({ onBack, onClose }: { onBack: () => void; onClose: () =>
-
-
- ShoeInn
-
-
-
+
Premium Care Marketplace
diff --git a/apps/mobile/src/screens/home/BookingTimeScreen.tsx b/apps/mobile/src/screens/home/BookingTimeScreen.tsx
index 12ec1ed..b02cc14 100644
--- a/apps/mobile/src/screens/home/BookingTimeScreen.tsx
+++ b/apps/mobile/src/screens/home/BookingTimeScreen.tsx
@@ -6,6 +6,7 @@ import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { useQuery } from "@tanstack/react-query";
import { getAvailability } from "../../api/http";
+import { Logo } from "../../components/branding/Logo";
import { AppScreen } from "../../components/ui/AppScreen";
import { Button } from "../../components/ui/Button";
import { Card, PressableCard } from "../../components/ui/Card";
@@ -184,12 +185,7 @@ function BookingTopBar({ onBack }: { onBack: () => void }) {
-
-
- ShoeInn
-
-
-
+
Premium Care Marketplace
@@ -319,7 +315,7 @@ function ServiceDetailsCard({
})}
/>
-
+
);
diff --git a/apps/mobile/src/screens/home/HomeScreen.test.tsx b/apps/mobile/src/screens/home/HomeScreen.test.tsx
index a062d02..6063194 100644
--- a/apps/mobile/src/screens/home/HomeScreen.test.tsx
+++ b/apps/mobile/src/screens/home/HomeScreen.test.tsx
@@ -167,7 +167,7 @@ describe("HomeScreen", () => {
const tree = renderComponent();
const output = JSON.stringify(tree.toJSON());
- expect(output).toContain("ShoeInn");
+ expect(output).toContain("Skruhb");
expect(output).toContain("Good Morning, ");
expect(output).toContain("Anthony");
expect(output).toContain("What needs care today?");
diff --git a/apps/mobile/src/screens/home/HomeScreen.tsx b/apps/mobile/src/screens/home/HomeScreen.tsx
index 3281fcc..b3208e3 100644
--- a/apps/mobile/src/screens/home/HomeScreen.tsx
+++ b/apps/mobile/src/screens/home/HomeScreen.tsx
@@ -9,6 +9,7 @@ import { LinearGradient } from "expo-linear-gradient";
import { getAppointmentAssignment, getMyAppointments, listCareCategories, listCompanies } from "../../api/http";
import { getDemoMarketDiscoveryLocation, shouldShowDemoLogins } from "../../auth/demoLogins";
import { ProviderCard } from "../../components/ProviderCard";
+import { Logo } from "../../components/branding/Logo";
import { AppScreen } from "../../components/ui/AppScreen";
import { Button } from "../../components/ui/Button";
import { CategoryTile } from "../../components/ui/CategoryTile";
@@ -20,7 +21,6 @@ import { SectionHeader } from "../../components/ui/SectionHeader";
import { SearchBar } from "../../components/ui/SearchBar";
import { StatusBadge, AppointmentStatusBadge } from "../../components/ui/StatusBadge";
import { Text } from "../../components/ui/Text";
-import { brandCopy } from "../../content/brandCopy";
import {
filterCompaniesByCategory,
getCategoryEmptyMessage,
@@ -230,12 +230,7 @@ export default function HomeScreen() {
-
-
- {brandCopy.appName}
-
-
-
+
PREMIUM CARE MARKETPLACE
diff --git a/apps/mobile/src/screens/profile/ProfileScreen.tsx b/apps/mobile/src/screens/profile/ProfileScreen.tsx
index fad5f99..d7ea700 100644
--- a/apps/mobile/src/screens/profile/ProfileScreen.tsx
+++ b/apps/mobile/src/screens/profile/ProfileScreen.tsx
@@ -139,7 +139,7 @@ export default function ProfileScreen() {
/>
diff --git a/apps/mobile/src/screens/provider/ProviderDashboardScreen.tsx b/apps/mobile/src/screens/provider/ProviderDashboardScreen.tsx
index 9039391..00e09d1 100644
--- a/apps/mobile/src/screens/provider/ProviderDashboardScreen.tsx
+++ b/apps/mobile/src/screens/provider/ProviderDashboardScreen.tsx
@@ -7,6 +7,7 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { claimAppointment, fetchMyAppointments, fetchOpenAppointments } from "../../api/http";
import { AppointmentCard } from "../../components/AppointmentCard";
+import { Logo } from "../../components/branding/Logo";
import { AppCard } from "../../components/AppCard";
import { AppScreen } from "../../components/ui/AppScreen";
import { Button } from "../../components/ui/Button";
@@ -110,12 +111,7 @@ export default function ProviderDashboardScreen() {
-
-
- ShoeInn
-
-
-
+
PROVIDER DISPATCH
diff --git a/apps/mobile/src/theme/theme.ts b/apps/mobile/src/theme/theme.ts
index d2eb3e2..178a364 100644
--- a/apps/mobile/src/theme/theme.ts
+++ b/apps/mobile/src/theme/theme.ts
@@ -1,11 +1,11 @@
import { StyleSheet, type TextStyle, type ViewStyle } from "react-native";
const palette = {
- ink900: "#1B1E24",
+ ink900: "#172126",
ink700: "#3B424C",
ink500: "#6F7782",
ink300: "#9BA3AD",
- porcelain: "#FAF8F4",
+ porcelain: "#F7F3EA",
cream: "#F8F5EF",
white: "#FFFFFF",
linen: "#F3EDE3",
@@ -14,8 +14,8 @@ const palette = {
border: "#E5DACE",
borderSoft: "#EFE7DC",
divider: "#EEE4D8",
- peacock: "#0B5563",
- peacockPressed: "#083F4A",
+ peacock: "#062E37",
+ peacockPressed: "#041F25",
teal: "#117B7C",
mint: "#CFE9E5",
gold: "#D6A73D",
@@ -202,28 +202,28 @@ export const textStyles = StyleSheet.create({
export const shadows = {
card: {
- shadowColor: "#1B1E24",
+ shadowColor: "#172126",
shadowOffset: { width: 0, height: 10 },
shadowOpacity: 0.07,
shadowRadius: 22,
elevation: 3,
} satisfies ViewStyle,
floating: {
- shadowColor: "#1B1E24",
+ shadowColor: "#172126",
shadowOffset: { width: 0, height: 16 },
shadowOpacity: 0.12,
shadowRadius: 32,
elevation: 7,
} satisfies ViewStyle,
modal: {
- shadowColor: "#1B1E24",
+ shadowColor: "#172126",
shadowOffset: { width: 0, height: 18 },
shadowOpacity: 0.16,
shadowRadius: 40,
elevation: 10,
} satisfies ViewStyle,
soft: {
- shadowColor: "#1B1E24",
+ shadowColor: "#172126",
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.05,
shadowRadius: 16,
diff --git a/apps/payment/README.md b/apps/payment/README.md
index 42afa0c..e55e7d6 100644
--- a/apps/payment/README.md
+++ b/apps/payment/README.md
@@ -1,4 +1,4 @@
-# ShoeInn Payment Service
+# Skruhb Payment Service
Optional FastAPI service that owns Stripe Checkout/PaymentIntent integration, payment records, Stripe webhook reconciliation, and payment-domain outbox rows.
@@ -67,7 +67,7 @@ Set in `apps/api/.env`:
```env
PAYMENT_MODE=service
PAYMENT_SERVICE_BASE_URL=http://localhost:8001
-PAYMENT_MOBILE_REDIRECT_BASE=shoeinn://app
+PAYMENT_MOBILE_REDIRECT_BASE=skruhb://app
```
For Expo Go:
@@ -79,7 +79,7 @@ PAYMENT_MOBILE_REDIRECT_BASE=exp://:8081/--
Then start the API:
```powershell
-.\scripts\start-api.ps1 -PaymentMode service -MobileRedirectBase "shoeinn://app"
+.\scripts\start-api.ps1 -PaymentMode service -MobileRedirectBase "skruhb://app"
```
## Stripe Webhooks
@@ -112,7 +112,7 @@ Payment tests set in-memory SQLite and test Stripe env defaults in `tests/confte
- The payment service creates tables at startup with SQLAlchemy metadata; there is no Alembic migration track in `apps/payment`.
- Outbox rows are persisted, but no local broker publisher is implemented in this repository.
-- Checkout can reuse Stripe Customers and eligible saved cards, but ShoeInn does not provide a separate card-management UI.
+- Checkout can reuse Stripe Customers and eligible saved cards, but Skruhb does not provide a separate card-management UI.
- Refund/dispute side effects are represented through payment state and compensating-action events; production support workflows remain future work.
## More Documentation
diff --git a/apps/payment/pyproject.toml b/apps/payment/pyproject.toml
index 235f8e4..48e78fd 100644
--- a/apps/payment/pyproject.toml
+++ b/apps/payment/pyproject.toml
@@ -1,5 +1,5 @@
[project]
-name = "shoeinn-payment"
+name = "skruhb-payment"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
diff --git a/brand/README.md b/brand/README.md
new file mode 100644
index 0000000..1e843d2
--- /dev/null
+++ b/brand/README.md
@@ -0,0 +1,12 @@
+# Skruhb brand assets
+
+The production identity is concept 45, **Compact SK ligature**, from Figma node `11:384` in the Skruhb logo exploration file.
+
+- `source/` preserves the exact SVG exports used to extract the approved outlined paths.
+- `svg/skruhb-logo-deep.svg` is the primary horizontal lockup for light backgrounds.
+- `svg/skruhb-logo-white.svg` is the horizontal lockup for dark backgrounds.
+- `svg/skruhb-logo-black.svg` is the pure-black horizontal lockup.
+- `svg/skruhb-symbol-*.svg` contains symbol-only variants for compact placements.
+- `svg/skruhb-app-icon.svg` contains the deep blue-green rounded-square treatment with the white ligature and warm-gold shared spine.
+
+All production SVGs use outlined paths and editable vector geometry; they contain no text nodes or font dependencies. Preserve their intrinsic aspect ratios, do not recolor them outside the approved palette, and provide layout clear space rather than cropping their view boxes.
diff --git a/brand/source/concept45-brand-figma.svg b/brand/source/concept45-brand-figma.svg
new file mode 100644
index 0000000..b5d1b32
--- /dev/null
+++ b/brand/source/concept45-brand-figma.svg
@@ -0,0 +1,18 @@
+
diff --git a/brand/source/concept45-lockup-figma.svg b/brand/source/concept45-lockup-figma.svg
new file mode 100644
index 0000000..7ae88d4
--- /dev/null
+++ b/brand/source/concept45-lockup-figma.svg
@@ -0,0 +1,19 @@
+
diff --git a/brand/source/concept45-symbol-figma.svg b/brand/source/concept45-symbol-figma.svg
new file mode 100644
index 0000000..ed4874c
--- /dev/null
+++ b/brand/source/concept45-symbol-figma.svg
@@ -0,0 +1,18 @@
+
diff --git a/brand/source/concept45-wordmark-figma.svg b/brand/source/concept45-wordmark-figma.svg
new file mode 100644
index 0000000..266e36f
--- /dev/null
+++ b/brand/source/concept45-wordmark-figma.svg
@@ -0,0 +1,14 @@
+
diff --git a/brand/svg/skruhb-app-icon.svg b/brand/svg/skruhb-app-icon.svg
new file mode 100644
index 0000000..b79b91a
--- /dev/null
+++ b/brand/svg/skruhb-app-icon.svg
@@ -0,0 +1,2 @@
+
diff --git a/brand/svg/skruhb-logo-black.svg b/brand/svg/skruhb-logo-black.svg
new file mode 100644
index 0000000..4277aa7
--- /dev/null
+++ b/brand/svg/skruhb-logo-black.svg
@@ -0,0 +1,2 @@
+
diff --git a/brand/svg/skruhb-logo-deep.svg b/brand/svg/skruhb-logo-deep.svg
new file mode 100644
index 0000000..dca3c1e
--- /dev/null
+++ b/brand/svg/skruhb-logo-deep.svg
@@ -0,0 +1,2 @@
+
diff --git a/brand/svg/skruhb-logo-white.svg b/brand/svg/skruhb-logo-white.svg
new file mode 100644
index 0000000..c6a42e5
--- /dev/null
+++ b/brand/svg/skruhb-logo-white.svg
@@ -0,0 +1,2 @@
+
diff --git a/brand/svg/skruhb-symbol-black.svg b/brand/svg/skruhb-symbol-black.svg
new file mode 100644
index 0000000..d762896
--- /dev/null
+++ b/brand/svg/skruhb-symbol-black.svg
@@ -0,0 +1,2 @@
+
diff --git a/brand/svg/skruhb-symbol-brand.svg b/brand/svg/skruhb-symbol-brand.svg
new file mode 100644
index 0000000..fe73189
--- /dev/null
+++ b/brand/svg/skruhb-symbol-brand.svg
@@ -0,0 +1,2 @@
+
diff --git a/brand/svg/skruhb-symbol-white.svg b/brand/svg/skruhb-symbol-white.svg
new file mode 100644
index 0000000..948146f
--- /dev/null
+++ b/brand/svg/skruhb-symbol-white.svg
@@ -0,0 +1,2 @@
+
diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md
index a966d38..fd55048 100644
--- a/docs/architecture/overview.md
+++ b/docs/architecture/overview.md
@@ -1,6 +1,6 @@
-# ShoeInn Architecture Overview
+# Skruhb Architecture Overview
-ShoeInn is a premium care marketplace demo composed of:
+Skruhb is a premium care marketplace demo composed of:
- React Native Mobile App
- FastAPI Backend API
@@ -102,4 +102,3 @@ flowchart LR
- [Environment reference](../environment.md)
- [Getting started](../getting-started.md)
- [Troubleshooting](../troubleshooting.md)
-
diff --git a/docs/architecture/payment.md b/docs/architecture/payment.md
index 907e504..1eb4ed7 100644
--- a/docs/architecture/payment.md
+++ b/docs/architecture/payment.md
@@ -37,7 +37,7 @@ API service mode:
```env
PAYMENT_MODE=service
PAYMENT_SERVICE_BASE_URL=http://localhost:8001
-PAYMENT_MOBILE_REDIRECT_BASE=shoeinn://app
+PAYMENT_MOBILE_REDIRECT_BASE=skruhb://app
```
## Webhooks
@@ -60,4 +60,3 @@ stripe listen --forward-to http://localhost:8001/payments/webhooks/stripe
- No local broker publisher for payment outbox rows.
- No separate card-management UI.
- Refund/dispute support exists at state/event level but production support workflows are future work.
-
diff --git a/docs/environment.md b/docs/environment.md
index 1a9c69f..3797f56 100644
--- a/docs/environment.md
+++ b/docs/environment.md
@@ -26,7 +26,7 @@ Read by `apps/api/app/core/config.py`.
| `PAYMENT_SERVICE_BASE_URL` | Required for service mode | blank | `http://localhost:8001` | Payment service base URL. |
| `PAYMENT_CHECKOUT_SUCCESS_URL` / `PAYMENT_SUCCESS_URL` | Optional | blank | `https://api.example.com/payments/return/success` | Browser success return URL alias. |
| `PAYMENT_CHECKOUT_CANCEL_URL` / `PAYMENT_CANCEL_URL` | Optional | blank | `https://api.example.com/payments/return/cancel` | Browser cancel return URL alias. |
-| `PAYMENT_MOBILE_REDIRECT_BASE` | Required for service mobile return path | blank | `shoeinn://app` | Mobile/frontend redirect base. Aliases: `PAYMENT_SUCCESS_URL_BASE`, `PAYMENT_RETURN_APP_URL`. |
+| `PAYMENT_MOBILE_REDIRECT_BASE` | Required for service mobile return path | blank | `skruhb://app` | Mobile/frontend redirect base. Aliases: `PAYMENT_SUCCESS_URL_BASE`, `PAYMENT_RETURN_APP_URL`. |
| `PAYMENT_SERVICE_TIMEOUT_SECONDS` | No | `10.0` | `10` | Timeout for payment-service calls. |
| `PAYMENT_CURRENCY` | No | `usd` | `usd` | Default payment currency. |
| `ENABLE_PAYMENT_SYNC_WORKER` | No | `true` | `true` | Starts payment sync worker when service mode is configured. |
@@ -45,8 +45,8 @@ Read by `apps/mobile/app.config.ts`, `src/api/http.ts`, `src/api/services.ts`, d
| `SHOW_DEMO_LOGINS` | No | `false` | `true` | Non-public fallback read by app config. |
| `EXPO_PUBLIC_DEMO_MARKET` | No | `shelby` | `mt_juliet` | Demo login/market selector. |
| `EXPO_PUBLIC_GOOGLE_MAPS_API_KEY` | Optional | none | `AIza...` | Enables Google Directions API route line, ETA, distance, and native map API keys. |
-| `EXPO_PUBLIC_MOBILE_REDIRECT_BASE` | Required for service payment return | none | `shoeinn://app` | Mobile return base for Stripe Checkout. |
-| `EXPO_PUBLIC_APP_URL` | Optional alias | none | `shoeinn://app` | Alias for mobile redirect base. |
+| `EXPO_PUBLIC_MOBILE_REDIRECT_BASE` | Required for service payment return | none | `skruhb://app` | Mobile return base for Stripe Checkout. |
+| `EXPO_PUBLIC_APP_URL` | Optional alias | none | `skruhb://app` | Alias for mobile redirect base. |
## Payment Service
@@ -64,4 +64,3 @@ Read by `apps/payment/app/config.py`.
| `BOOKING_API_WEBHOOK_SECRET` | No | none | `replace-me` | Optional callback header secret. |
| `DEFAULT_CURRENCY` | No | `usd` | `usd` | Payment default currency. |
| `PAYMENT_ALLOW_TEST_CLOCK` | No | `true` | `true` | Allows Stripe test clock behavior in non-production testing. |
-
diff --git a/docs/getting-started.md b/docs/getting-started.md
index 637945d..dc0198e 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -92,16 +92,16 @@ The helper script can do the same setup:
Shelby County demo, password `Password1!`:
-- Customer: `customer@shoeinn.com`
-- Provider: `pelham.driver1@shoeinn.com`
-- Company admin: `pelham.admin@shoeinn.com`
-- Global admin: `admin@shoeinn.com`
+- Customer: `customer@skruhb.com`
+- Provider: `pelham.driver1@skruhb.com`
+- Company admin: `pelham.admin@skruhb.com`
+- Global admin: `admin@skruhb.com`
Mt. Juliet demo, password `Password123!`:
-- Customer: `customer.mtjuliet@shoeinn.demo`
-- Provider: `provider.mtjuliet@shoeinn.demo`
-- Company admin: `admin.mtjuliet@shoeinn.demo`
+- Customer: `customer.mtjuliet@skruhb.demo`
+- Provider: `provider.mtjuliet@skruhb.demo`
+- Company admin: `admin.mtjuliet@skruhb.demo`
To show demo login buttons:
@@ -148,10 +148,10 @@ Company admin:
3. Start API in service mode:
```powershell
-.\scripts\start-api.ps1 -PaymentMode service -MobileRedirectBase "shoeinn://app"
+.\scripts\start-api.ps1 -PaymentMode service -MobileRedirectBase "skruhb://app"
```
-4. Start mobile with `EXPO_PUBLIC_MOBILE_REDIRECT_BASE=shoeinn://app` for a dev build, or an `exp://.../--` URL for Expo Go.
+4. Start mobile with `EXPO_PUBLIC_MOBILE_REDIRECT_BASE=skruhb://app` for a dev build, or an `exp://.../--` URL for Expo Go.
## 8. Validate Before Making Changes
@@ -178,4 +178,3 @@ cd .\apps\payment
.\.venv\Scripts\Activate.ps1
python -m pytest tests -q
```
-
diff --git a/docs/staging.md b/docs/staging.md
index dbd89ba..fda30d1 100644
--- a/docs/staging.md
+++ b/docs/staging.md
@@ -1,6 +1,6 @@
# Staging Runbook
-This runbook describes the current Docker Compose staging slice for ShoeInn.
+This runbook describes the current Docker Compose staging slice for Skruhb.
## Scope
@@ -96,7 +96,7 @@ Critical values:
EXPO_PUBLIC_API_URL=https://api-staging.example.com
EXPO_PUBLIC_API_BASE_URL=https://api-staging.example.com
EXPO_PUBLIC_ENABLE_DEMO_LOGINS=true
-EXPO_PUBLIC_MOBILE_REDIRECT_BASE=shoeinn://payment-return
+EXPO_PUBLIC_MOBILE_REDIRECT_BASE=skruhb://payment-return
```
Do not point staging mobile builds at localhost.
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 2dfb446..78d8f06 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -54,7 +54,7 @@ If native config changed, rebuild the dev client instead of relying on Expo Go.
- Run `npx eas credentials`.
- Regenerate credentials only if the existing profile/certificate is invalid.
-- Make sure the bundle identifier remains `com.mrwrite.shoeinn`.
+- Make sure the bundle identifier remains `com.mrwrite.skruhb`.
## Maps
diff --git a/scripts/start-api.ps1 b/scripts/start-api.ps1
index 4c87d43..b3c38cd 100644
--- a/scripts/start-api.ps1
+++ b/scripts/start-api.ps1
@@ -131,7 +131,7 @@ try {
$effectivePaymentServiceBaseUrl = "http://localhost:8001"
}
if (-not $effectiveMobileRedirectBase) {
- throw "PAYMENT_MODE=service requires -MobileRedirectBase, for example exp://:8081/-- for Expo Go or shoeinn://app for a dev build."
+ throw "PAYMENT_MODE=service requires -MobileRedirectBase, for example exp://:8081/-- for Expo Go or skruhb://app for a dev build."
}
try {
Invoke-RestMethod "$($effectivePaymentServiceBaseUrl.TrimEnd('/'))/health" | Out-Null
diff --git a/scripts/start-mobile.ps1 b/scripts/start-mobile.ps1
index ce3fb48..645e46d 100644
--- a/scripts/start-mobile.ps1
+++ b/scripts/start-mobile.ps1
@@ -49,7 +49,7 @@ try {
$apiPort = ([uri]$ApiBaseUrl).Port
} catch {
}
- throw "Could not reach the ShoeInn API at $healthUrl. Check the API window for startup errors, confirm the API is running on port $apiPort, verify the LAN IP in -ApiBaseUrl, and confirm Windows Firewall allows inbound connections."
+ throw "Could not reach the Skruhb API at $healthUrl. Check the API window for startup errors, confirm the API is running on port $apiPort, verify the LAN IP in -ApiBaseUrl, and confirm Windows Firewall allows inbound connections."
}
if ($ExpectedPaymentMode) {