Skip to content

feat(golf): Golf Canada profile page with live handicap index and recent scores - #99

Merged
kenjdavidson merged 3 commits into
mainfrom
copilot/add-golf-canada-plugin
Mar 16, 2026
Merged

feat(golf): Golf Canada profile page with live handicap index and recent scores#99
kenjdavidson merged 3 commits into
mainfrom
copilot/add-golf-canada-plugin

Conversation

Copilot AI commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Adds a /golf page that fetches live Golf Canada data at build time — handicap index, recent scores, and season stats — using credentials from environment variables.

New files

  • src/utils/golf-canada.ts — build-time API client: authenticates via the Golf Canada token endpoint, fetches the member snapshot, validates both responses before casting, and stamps a fetchedAt ISO timestamp. Returns null when credentials are absent so local dev renders a graceful fallback.
// GOLFCANADA_USERNAME + GOLFCANADA_PASSWORD env vars required at build time
export async function getGolfCanadaProfile(): Promise<GolfCanadaProfile | null>
  • src/pages/golf.astro — two-column layout (mirrors /about):
    • Secondary (sticky sidebar): initials avatar, handicap index hero, career low with date, YTD rounds/avg-score stat grid
    • Main column: recent scores table (course, date, holes, score, used-in-calc indicator), attribution + fetchedAt timestamp

Modified files

  • Header.astro — Golf nav link added between Projects and About
  • FloatingActionButton.tsxFiDisc added to FabIconName union + ICON_MAP
  • BaseLayout.astro — Golf FAB shortcut at position 9; About moved to position 7

Deploy

Add GOLFCANADA_USERNAME and GOLFCANADA_PASSWORD as GitHub Actions secrets — the build fetches and bakes in live data on every deployment.

Screenshots

Golf page (with live data):

Updated navigation:

Original prompt

This section details on the original issue you should resolve

<issue_title>Feature - Golf Canada plugin</issue_title>
<issue_description>Implement source plugin and React Components for access/display of Golf Canada.

  • Generated the Golf Canada client, that will wrap calls to the API
  • Generate the /golf page that will contain the profile
  • Setup the build/deploy script to look for GOLFCANADA_USERNAME and GOLFCANDA_PASSWORD in env vars / github secrets

Login:

Performed with the following request

https://scg.golfcanada.ca/connect/token
grant_type: password
password: GOLFCANADA_PASSWORD
scope: address email offline_access openid phone profile roles
username: GOLFCANADA_USERNAME

the object response is:

{
    "token_type": "Bearer",
    "access_token": <ACCESS_TOKEN>,
    "expires_in": 3600,
    "refresh_token": <REFRESH_TOKEN>,
    "id_token": <TOKEN>,
    "user": {
        "id": 1538533,
        "authUserId": 1673106,
        "networkId": 3234132,
        "golfCanadaCardId": "5200043264",
        "username": "KENJDAVIDSON",
        "fullName": "Ken Davidson",
        "firstName": "Ken",
        "lastName": "Davidson",
        "handicap": "8.9",
        "pcc": "",
        "email": "ken.j.davidson@live.ca",
        "isAdmin": false,
        "isNationalAdmin": false,
        "isNationalLookupAdmin": false,
        "isAssociationAdmin": false,
        "isSystemAdmin": false,
        "isTournamentAdmin": false,
        "isHandicapChair": false,
        "isLimitedClubAdmin": false,
        "isPending": false,
        "membershipLevel": "Gold",
        "expirationDate": "2027-02-01T00:00:00",
        "clubManagementGroupId": 8,
        "termsAndConditionsDate": "2025-06-25T11:42:54",
        "isClubManagingUpgrades": true,
        "allowScorePosting": true,
        "subscriptionRenewsOn": null,
        "scoreDefaults": {
            "nationalAssociation": "RCGA",
            "facilityId": 20598,
            "facilityName": "Blue Springs Golf Club",
            "courseId": 20599,
            "teeId": 83281,
            "postHoleByHole": true
        }
    },
    "expire_date": "2026-03-16T14:40:25.0495707Z"
}

Snapshot

A snapshot of the profile is requested with

https://scg.golfcanada.ca/api/members/1538533/getSnapshot

and returns

{
    "club": "Blue Springs Golf Club",
    "membershipType": "Gold",
    "expirationDate": "2027-02-01T00:00:00",
    "homeCourse": null,
    "defaultTee": null,
    "courseHandicap": "NH",
    "winterHandicap": "NH",
    "winterCourseHandicap": "NH",
    "isWinterHandicapDisplayed": false,
    "scores": [
        {
            "course": "West Woods Golf Club (Cottonwood/Silo)",
            "datePlayed": "2025-12-27T00:00:00",
            "holesPlayed": 9,
            "score": 40,
            "isUsedInCalc": false
        },
        {
            "course": "Dragon's Fire Golf Club",
            "datePlayed": "2025-11-23T00:00:00",
            "holesPlayed": 18,
            "score": 80,
            "isUsedInCalc": false
        },
        {
            "course": "Hidden Lake Golf Club - NEW COURSE",
            "datePlayed": "2025-11-02T00:00:00",
            "holesPlayed": 18,
            "score": 88,
            "isUsedInCalc": false
        },
        {
            "course": "Hidden Lake Golf Club - OLD COURSE",
            "datePlayed": "2025-11-01T00:00:00",
            "holesPlayed": 18,
            "score": 83,
            "isUsedInCalc": false
        },
        {
            "course": "Blue Springs Golf Club",
            "datePlayed": "2025-10-26T00:00:00",
            "holesPlayed": 18,
            "score": 88,
            "isUsedInCalc": false
        }
    ],
    "clubManagementGroup": "GolfAssociationOfOntario",
    "ytdScoreCount": 0,
    "ytdScoreAverage": 0.0,
    "ytdYear": 2026,
    "transferClubName": null,
    "transferRequestDate": null,
    "lastCardRequestedOn": "2019-04-10T13:19:37.807",
    "expectedDeliveryOn": null,
    "isCardsSentToClub": false,
    "lowHandicap": "5.8",
    "lowHandicapOn": "2025-09-06T00:00:00",
    "adjustedLowHandicap": "NH",
    "displayLowHandicap": "5.8",
    "adjustedLowHandicapStartOn": null,
    "adjustedLowHandicapEndOn": null,
    "lowHandicapAdjustedOn": null,
    "isLowIndexAdjusted": false,
    "subscriptionRenewsOn": null
}

Page Layout

I'm curious to see what you'll do on your own. The profile shouldn't show any personal information, it should be solely golf related. It hsould include things like: profile image, name, handicap, recent scores, etc. The profile should be desktop and mobile friendly. It wil be possible to use the two column layout as you see fit.</issue_description>

Comments on the Issue (you are @copilot in this section)


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

…nt scores

Co-authored-by: kenjdavidson <6210735+kenjdavidson@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Golf Canada plugin and components feat(golf): Golf Canada profile page with live handicap index and recent scores Mar 16, 2026
Copilot AI requested a review from kenjdavidson March 16, 2026 13:58
@kenjdavidson
kenjdavidson marked this pull request as ready for review March 16, 2026 15:05
Comment thread src/pages/golf.astro Outdated
</dd>
</div>
<div class="flex justify-between">
<dt class="text-gray-500 dark:text-gray-400 font-medium">Expires</dt>

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the expiration date of the account, this should be considered somewhat PII.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in c292918. The "Expires" row is gone from the profile card — only the handicap index and career low remain.

Comment thread src/pages/golf.astro Outdated
<div class="flex justify-between items-center">
<dt class="text-gray-500 dark:text-gray-400 font-medium">Membership</dt>
<dd>
<span class="inline-block px-2 py-0.5 rounded-full text-xs font-semibold bg-brand-100 dark:bg-brand-900/40 text-brand-700 dark:text-brand-300">

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Membership type is not required, also somewhat PII.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in c292918. The "Membership" badge is gone. Updated profile card:

Updated golf profile card — no membership type or expiry

…PII)

Co-authored-by: kenjdavidson <6210735+kenjdavidson@users.noreply.github.com>

Copilot AI commented Mar 16, 2026

Copy link
Copy Markdown
Contributor Author

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • telemetry.astro.build
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/kenjdavidson.github.io/kenjdavidson.github.io/node_modules/.bin/astro build (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@kenjdavidson
kenjdavidson merged commit e33a4b3 into main Mar 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature - Golf Canada plugin

2 participants