Skip to content

Latest commit

 

History

25 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Languages: English | Русский

REMS-desk — Frontend (client)

Web client for REMS-desk, a system for tracking office-equipment repair & maintenance requests. It is a dependency-free, no-bundler vanilla JavaScript (ES modules) + HTML + CSS application. The same static files power the marketing landing page and the role-based dashboard (owner / employee / solo). In production the files are served by the backend itself (Express express.static), so there is no separate frontend host.


Table of contents


For end users

REMS-desk helps an organization run its equipment-repair workflow end to end:

  • Sign up / sign in with email (SMS is built but disabled by a feature flag), a 6-digit verification code, a password and a 6-digit PIN (re-asked on return).
  • Three roles, auto-detected from your account:
    • Owner — manages the organization, employees, equipment catalog, partner contracts and sees all requests.
    • Employee — handles requests, sees the equipment catalog and colleagues.
    • Solo — a user without an organization; can create a personal home, request membership or accept an invitation.
  • Requests — create, take, progress and close repair requests with priorities, two-clock SLA (response + resolution), a road-map of statuses, and photo/document attachments.
  • Catalog — register equipment with photos, categories, warranty progress.
  • Partners / contracts — owners set up inter-organization contracts with their own SLA matrix and contract documents.
  • Notifications — in-app feed, corner toasts, sound, and (optional) native OS/browser notifications when the tab is in the background.
  • Languages — full Russian / English UI, switchable at any time.
  • Privacy — no tracking cookies; only localStorage is used (session token, language, UI flags). A one-time notice says so on the landing page.

For developers

Stack: plain ES modules (no build step, no framework), CSS custom properties, fetch, WebSocket via Socket.IO client, Intl for i18n.

How it is served & cache-busted. Every page is plain HTML. The backend serves these files and, in dev, rewrites local src/href with a per-boot ?v=BOOT_ID cache-buster and injects a service-worker killer. HTML partials are assembled server-side via <!--#include "..."> directives (see pages/partials).

Pages.

JS architecture. Entry points per page (js/pages/*.js). The dashboard boots from js/pages/dashboard/index.js, which wires chrome modules and delegates to a role router that mounts the right dashboard (owner / employee / solo). Shared concerns live in small, single-purpose modules injected by dependency (e.g. switchTab is passed into chrome modules rather than imported globally).

Networking. js/api.js is the typed REST wrapper, js/auth.js handles the session token / logout, js/socket.js the realtime channel. All API URLs are relative, so the client works on any origin.

i18n. js/i18n.js loads locales/ru.json / locales/en.json, translates data-i18n* attributes, and exposes t(), setLang(), onLangChange(). Backend error keys mirror the locale JSON structure 1:1, so t(error_key) resolves directly.

Responsive model. Fluid, breakpoint-light chrome (see css/chrome.css and css/responsive.css): the navbar/content margins shrink symmetrically; below 768px the dashboard sidebar becomes a bottom nav, the header matches the landing header, and notifications move into a modal.

For the administrator (me)

  • Hosting: one Railway service for the whole repo — the backend builds and runs, and serves this frontend/ folder as static files. There is no separate static host. See the backend README for the Railway setup.
  • The only deploy-time switch that touches the client is the public URL (FRONTEND_URL on the backend) — point it at https://rems-desk.ru. The client itself needs no edits because all of its API/asset URLs are relative.
  • Capability flags (js/config.js) come from the backend (GET /api/config). sms:false hides phone UI everywhere; email:true enables real email. Safe defaults hide unfinished channels even if the config fetch fails.
  • Brand / email-deliverability assets that you configured externally: bimi/logo-bimi.svg (BIMI logo shown next to emails) and assets/og-image.png (social preview).

Engineering principles

  • No build, no dependencies. Ship the source as-is; the browser runs ES modules directly. This keeps the client auditable and host-agnostic.
  • Modular / atomic. Many small files with one responsibility each; composition over inheritance; dependencies passed in (DI) rather than reached for globally.
  • CSS manifest. style.css is a thin manifest that @imports the files in css/; design tokens live in css/tokens.css (CSS custom properties) — no hard-coded colors/spacing in components.
  • Server-side HTML includes. Pages are composed from partials via <!--#include-->, expanded by the backend — one assembled document, no client templating engine.
  • Capability flags, not environment checks. Feature availability is driven by explicit flags from the backend, never by dev/prod sniffing.
  • RLS-friendly, stateless client. The client holds only a JWT; all authorization is enforced server-side (PostgreSQL Row-Level Security).

Third-party assets & libraries

What Where it comes from Used for Files
Phosphor Icons self-hosted (no CDN), from https://phosphoricons.com all UI icons (<i class="ph ...">) vendor/phosphor/
Vanta.js WAVES + three.js self-hosted, https://www.vantajs.com / https://threejs.org animated hero background on the landing vendor/ (vanta.waves.min.js, three.min.js)
Onest font self-hosted, https://github.com/Solbera-Lab/Onest brand typography fonts/onest.css + font files
Socket.IO client served by backend at /socket.io/socket.io.js realtime notifications loaded in pages/dashboard.html

Everything is self-hosted — the app runs with no external CDN.

Running & testing

The client is served by the backend, so the normal way to run it is to start the backend (it serves ../frontend). See the backend README for npm run dev. There is no separate build or test command for the client (no bundler, no framework). To preview just the static files you may serve this folder with any static server, but API calls will fail without the backend.

Full file & folder reference

Root

Path Purpose
index.html Marketing landing page (hero, Vanta animation, dashboard preview, features, stats, footer, cookie notice). Also holds the SEO <head>: title/description/keywords/canonical, Open Graph + Twitter cards, and Schema.org JSON-LD.
style.css CSS manifest — @imports every file in css/.
sitemap.xml Search-engine sitemap (home + login/register; private/auth pages excluded). Served at /sitemap.xml.
robots.txt Crawler rules — allow public pages, disallow /api/, dashboard, uploads; links the sitemap. Served at /robots.txt.
README.md / README.ru.md This documentation (EN / RU).
LICENSE License.

SEO note: the code makes the site indexable. To actually appear in results, register the domain once in Google Search Console, Yandex Webmaster and Bing Webmaster Tools and submit sitemap.xml.

assets/ — brand & PWA assets

File Purpose
logo.svg Primary wordmark.
logo-full.svg Full wordmark (desktop navbar).
logo-compact.svg Compact wordmark (mobile/narrow navbar).
logo-icon.svg Square badge icon only.
favicon.ico, favicon.svg, favicon-16x16.png, favicon-32x32.png Favicons.
apple-touch-icon.png, android-chrome-192x192.png, android-chrome-512x512.png PWA / mobile icons (also used by OS notifications).
site.webmanifest PWA manifest.
og-image.png Social/Open-Graph preview image.
File Purpose
logo-bimi.svg BIMI-spec logo for showing the brand mark next to emails (DNS/Cloudflare configured externally).

css/ — styles (imported by style.css)

File Purpose
tokens.css Design tokens — color/spacing/radius/typography CSS variables.
base.css Resets and base element styles.
buttons.css Button system (variants, icon buttons).
forms.css Inputs, selects, validation states.
components.css Shared components (cards, badges, chips, avatars).
chrome.css App chrome — fluid navbar, sidebar, content margins, sidebar scrim.
nav.css Navigation / sidebar items.
modal.css Modal dialogs and backdrops.
feedback.css Toasts and skeletons.
notifications.css Notification feed and corner-toast cards.
profile.css Profile/organization tabs, list-fill blocks, request feed, pickers, tooltips.
auth.css Login / register / PIN-lock screens.
landing.css Landing-page sections (hero text, features, footer, mobile preview).
empty-state.css Empty-state illustrations.
misc.css Language switcher and small one-offs.
responsive.css All responsive rules incl. mobile dashboard nav, request sub-filters, role-based visibility.
File Purpose
onest.css @font-face declarations for the self-hosted Onest font (+ font files alongside).

vendor/ — self-hosted third-party libs

Path Purpose
vendor/phosphor/ Phosphor Icons CSS (regular, bold, fill, duotone) + webfonts.
vendor/three.min.js, vendor/vanta.waves.min.js three.js + Vanta WAVES for the hero animation.
File Purpose
ru.json / en.json All UI strings + backend error-key translations (structure mirrors backend error_keys).
File Purpose
notification.mp3 Notification sound (primed on first user gesture to satisfy autoplay policy).

pages/ — non-landing HTML

File Purpose
dashboard.html Dashboard shell: pre-paint loader, PIN-lock overlay, navbar, sidebar, all tab panels, modal includes.
login.html Login (+ password/PIN reset flows).
register.html Multi-step registration.

pages/partials/dashboard/ — server-included fragments

File Purpose
account.html Account section markup.
contacts.html Contact-change modals.
contracts.html Contract create/view/edit modals.
equipment.html Equipment create/edit/photo modals.
members.html Member management / invite modals.
membership.html Join / leave / invitation modals.
requests.html Request create/detail/road-map modals.
sessions.html Active-sessions markup.

js/ — top-level modules

File Purpose
api.js REST client — one method per backend endpoint group; relative URLs.
auth.js Session token storage, logout(), toast helper, error mapping.
config.js Capability flags (email/sms) loaded from GET /api/config.
i18n.js Locale loading, t(), setLang(), switcher wiring, DOM translation.
socket.js Socket.IO connection + auth handshake for realtime events.
device-id.js Stable per-device id (random, localStorage) — no fingerprinting, no CDN.
form-guard.js Guards against duplicate/last-submit form resubmission.
media-attach.js Shared file-attach widget (temp upload → confirm) used by modals.

js/lib/ — reusable UI primitives

File Purpose
char-counter.js Live character counters under modal fields.
code-input.js Segmented verification-code input.
doc-preview.js Document/file preview tile.
lazy-loader.js Attaches loading/error UI to async loaders.
media-viewer.js Full-screen image viewer.
page-loader.js Pre-paint page loader control.
pin-gate.js One-shot PIN pass (skip PIN right after login/register).

js/pages/ — page entry points

File Purpose
login.js Login page logic + reset flows.
register.js Multi-step registration (incl. re-submitting the verified code).

js/pages/dashboard/ — dashboard core

File Purpose
index.js Dashboard boot: auth/PIN gate, tab switching, chrome wiring, socket events.
role-router.js Detects role and mounts the matching dashboard.
notifications.js Notification state, feed render, corner toasts, sound, OS notifications.
members.js Members tab logic (list, pending, approve/reject, invite).
sessions.js Active sessions list + revoke.
pin-lock.js PIN-lock overlay on return.
format.js Formatting helpers (dates, initials, avatars, role labels).
badges.js Status/role badge helpers.
dom-utils.js q() and small DOM helpers.
ui-helpers.js Modal open/close, modal lang-switcher injection.
File Purpose
sidebar.js Sidebar toggle, narrow-screen auto-collapse, scrim.
user-dropdown.js Avatar menu; profile/org/logout links (incl. profile-bottom logout).
notifications-button.js Bell → notifications modal (mobile) / overview (desktop); OS-permission request.
subfilter-wrap.js Marks wrapped request sub-filter groups to drop the leading separator.
File Purpose
requests.js Request feed: load, filter, segment, render, road-map.
requests-ui.js Request card / chip / SLA rendering.
equipment.js Equipment data + catalog logic.
equipment-ui.js Equipment card / status rendering.
contracts-ui.js Contract card / SLA-matrix rendering.
role-helpers.js show()/hide()/remove() role-visibility helpers.
File Purpose
index.js Owner orchestrator.
overview.js Owner overview (tiles, sub-filters, request work area).
requests.js Owner requests tab.
catalog.js Equipment catalog (CRUD).
partners.js Partners/contracts tab.
contracts.js Contract create/edit modals.
team.js Employees/colleagues management.
File Purpose
index.js Employee orchestrator.
overview.js Employee overview (membership card, personal stats, leave-org).
requests.js Employee requests tab (feed + notifications).
catalog.js Read-only equipment catalog.
contracts.js Read-only contracts.
team.js Colleagues list.
File Purpose
index.js Solo orchestrator.
home.js Solo home (request membership / accept invite / notifications).
join-modal.js Join-an-organization modal.
File Purpose
change-password.js Change-password flow.
change-pin.js Change-PIN flow.
change-contact.js Change email/phone flow.
detach-contact.js Detach a contact channel.
field-edit.js Generic single-field edit modal.
File Purpose
profile.js Personal profile tab rendering.
organization.js Organization tab (info, SLA matrix, limits).

About

Web client for REMS-desk, a system for tracking office-equipment repair & maintenance requests. It is a dependency-free, no-bundler vanilla JavaScript (ES modules) + HTML + CSS application.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages