Skip to content

My Company Emissions dashboard

“My Company Emissions” is the Carbon Calculator’s landing page for a logged-in user: this year’s total in tCO2e, the Scope 1/2/3 split, carbon intensity per £1m turnover, a year-over-year chart, and the table of the company’s reports.

It is the answer to “what are our emissions?” in one screen, and the entry point to everything else — creating or continuing a report, and sharing with clients. It also has to degrade gracefully for the large fraction of users who arrive with no company link, no reporting years configured, or no calculation run yet.

PathWhat it does
wp-content/themes/carboncalculator/page-my-company-emissions.phpThe page template, /my-company-emissions/
wp-content/themes/carboncalculator/assets/js/company-emissions.jsChart rendering and the scope filter buttons
wp-content/themes/carboncalculator/partials/components/reports-table.phpThe reports table markup
wp-content/themes/carboncalculator/assets/js/reports-table.jsTable sorting and row actions
wp-content/themes/carboncalculator/assets/js/create-report-modal.js“Create report” flow
wp-content/themes/carboncalculator/functions.php:1413carboncalculator_build_company_reports_table_rows()
wp-content/themes/carboncalculator/functions.php:1481carboncalculator_get_company_emissions_chart_series()
wp-content/themes/carboncalculator/functions.php:1313carboncalculator_format_report_intensity_display()
wp-content/themes/carboncalculator/index.phpFront page; redirects logged-in users here

The template runs entirely server-side before get_header() (page-my-company-emissions.php:1-135):

  1. Auth. If carboncalculator_auth_required() and there is no LMS user with an email, redirect to home_url('/'). CARBONCALC_SKIP_AUTH disables this.
  2. Company. CarbonCalc\LMS::company_id(). Zero triggers carboncalculator_log_company_not_linked_dashboard(), which writes a carbon_calculator_company_not_linked line to wp-content/carboncalc-login-denied.log, and the page renders a “Company not linked” notice instead of data.
  3. Year selection. ?reporting_year_id= is validated against the list of real years (in_array against ids at :29 — an unknown value falls back, it does not error). With no param it prefers the year of the company’s most recent report, else the first year in the list.
  4. Report and result. carboncalculator_get_company_report_for_year() then carboncalculator_get_report_result_row().
  5. Totals. Prefer cc_report_result.total_tco2e; fall back to s1 + s2 + s3. $cc_has_calculation is true if the total column is non-null or the scope sum is greater than zero (:69) — so a genuinely zero-emission report reads as “not calculated yet”.
  6. Intensity. total ÷ (turnover in £m), from carboncalculator_get_report_turnover_gbp() which reads the turnover answer off the report. Displayed as tCO2e / £1m.
  7. Chart. carboncalculator_get_company_emissions_chart_series() builds labels and values across the company’s years. The chart column is hidden unless there are at least two data points (:153, :316).
  8. Buttons. Label depends on report status — “Continue {year} report” for draft, “Edit Report” for submitted/completed, “Create {year} report” when none exists (:107-131). The create/share buttons only render when carboncalculator_user_can_create_reports() is true, and “Share with clients” additionally requires carboncalculator_is_sharing_enabled().
  9. Reports table. partials/components/reports-table.php with rows from carboncalculator_build_company_reports_table_rows().

Data is passed to JavaScript through data- attributes on #company-emissions-dashboard (:151-153) — chart labels, values, and a show/hide flag — rather than wp_localize_script.

Report URLs use the report UUID, not the numeric id (add_query_arg('report_id', strtolower($cc_report['uuid']), …) at :108). UUIDs were added in schema v13 (Migrations.php:300) precisely so report links are not guessable by incrementing an integer.

Formatting helpers all live in carboncalculator/functions.php: carboncalculator_format_tco2e_display() (:1291), carboncalculator_format_compact_tco2e() (:3784), carboncalculator_format_compact_gbp() (:3751), carboncalculator_format_dashboard_total_spend_gbp() (:3770).

  • CARBONCALC_SKIP_AUTH — bypass the login redirect (local only).
  • carboncalc_feature_sharing_enabled — shows the “Share with clients” button.
  • Reporting years must exist in cc_reporting_year, or the page renders “No reporting years available”.
  • Page slugs are hard-coded in the template: /my-company-emissions/, /my-company-emissions/carbon-emissions-report/, /my-company-emissions/share-carbon-emissions-report/ (:101, :102, :223). Renaming the WordPress pages breaks these links.
  • A report with a true zero total shows as “not calculated yet”. $cc_has_calculation (:69) treats a NULL total plus zero scopes as uncalculated, which is correct for a fresh report and wrong for a company with genuinely nil declared emissions.
  • The page renders for a user with no company rather than redirecting — intentional, so support can see the “Company not linked” state. It also writes a log line on every such page load, so a single stuck user produces a lot of log volume.
  • The chart hides below two data points. A company’s first year always shows a full-width summary with no chart; this is by design, not a bug.
  • Intensity is null unless both a calculation and a turnover answer exist; the UI renders an en dash. Turnover comes from the questionnaire, so a report can be fully calculated and still have no intensity.
  • Year selection silently falls back on an invalid reporting_year_id. No 404, no notice.
  • page-my-company-emissions.php.bak exists in the theme directory. It is dead weight and not loaded; do not edit it by accident.
  • Server-side data prep belongs in carboncalculator/functions.php as a carboncalculator_* function called from the template’s header block. Keep the template’s top section free of markup — everything above get_header() at :136 is data assembly.
  • New dashboard numbers: add a formatter next to the existing carboncalculator_format_* helpers so rounding and unit display stay consistent, then pass to JS via a data- attribute on the dashboard div.
  • Changing page slugs requires editing the hard-coded URLs at :101, :102 and :223, plus redirect_targets_carbon_calculator() in themes/supplychainschool/inc/classes/LMSClient.php:1133, which string-matches those same slugs to decide whether a login is a Carbon login. Missing that second one silently breaks role sync on login.
  • Assets are built with Gulp + Tailwind. Run npm run prod in wp-content/themes/carboncalculator and commit assets/css and assets/js — the compiled output is tracked. Tailwind scans **/*.php, so a class only used in a JS template literal will be purged.
  • Verify by hand, in this order, because each is a distinct code path:
    1. Guest → redirected to /.
    2. Logged in, no company → “Company not linked”.
    3. Company, no years → “No reporting years available”.
    4. Company with a draft → “Continue {year} report”.
    5. One calculated year → totals, no chart.
    6. Two calculated years → chart appears.

None. No PHP or JS test setup in either theme.

Related: [[emissions-calculation-and-submission]], [[carbon-report-questionnaire]], [[report-sharing]], [[supply-chain-emissions]], [[carbon-access-gates]].