=== Squadeno - Club Sports Manager ===
Contributors: tschiffler
Tags: sports, club, calendar, courses, training
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.9.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Training times, trainers and events for sports clubs, with a calendar that keeps itself current and blocks school holidays automatically.

== Description ==

In most clubs the training schedule exists. Getting it onto the website and keeping it there is the work. The plan lives in a PDF that is two seasons old, the summer break is still not on the calendar, and the person who knows when the hall is free is away for three weeks.

Squadeno turns that around. You maintain the training schedule once, say Tuesday at 6 pm in the gym hall from September to June, and every single date is generated from it. Closures and school holidays block the affected sessions automatically. A cancelled session, a moved date or an extra session is handled on the date itself, and the change shows up everywhere that sport appears.

**Who it is for:** clubs with more than a handful of offerings that want every sport to have its own findable page, and that want trainers to keep their own dates current without being handed the keys to the whole site.

= What you get =

* **Sports** with their own SEO-friendly page; optional subgroups/disciplines (e.g. athletics → kids/youth).
* **Training times** per sport – season- and weather-aware; location as a venue or free text.
* **Automatic calendar**: dates are generated from the training schedule, holidays/closures block automatically, exceptions (cancelled/rescheduled/extra date) and events are added on top.
* **Trainers** with their own profile page; any number per sport (main/assistant/substitute).
* **Venues** with address, GPS, photo and an automatic "what takes place here" list.
* **Events** via a simple builder (open/registration, costs, single- or multi-day).
* **Roles**: the editorial team maintains everything; trainers edit only their assigned sports and their own profile.
* **SEO**: clean URLs, internal linking and structured data (schema.org).
* **Performance**: computed dates are cached (transient) and refreshed automatically on changes.

The source language of the plugin is English; a complete German translation (de_DE) is bundled. Public URL slugs default to English and can be localized per site in the settings.

= Putting it on the page =

Shortcodes (blocks with the same output are also available):

* `[csmgr_sports]` – overview of all sports with filters (age group/section).
* `[csmgr_calendar view="month"]` – club-wide calendar (`view="month"`, `view="week"` or `view="list"` for the weekly training schedule).
* `[csmgr_upcoming sport="ID" limit="5"]` – upcoming dates of a sport.

= More about the plugin =

The project page at [squadeno.com](https://squadeno.com) covers the same ground in more detail, with larger screenshots and a German version of the text.

= Privacy by default =

Maps are optional and switched off by default: no map data is requested from any external server until an administrator selects the map provider "OpenStreetMap" in the settings. The Leaflet map library (BSD-2-Clause) is bundled with the plugin and served locally; it is not loaded from a CDN.

== External services ==

This plugin relies on the following third-party services. It does not send any data unless the corresponding feature is used.

**OpenStreetMap map tiles (optional, disabled by default)** – Maps are off out of the box: the setting "Map provider" (Club Sports → Settings → Calendar & maps) defaults to "none", and while it is set to "none" the plugin contacts no map server at all, neither on the public website nor in the WordPress admin area. Only after an administrator explicitly selects "OpenStreetMap" does the browser load map tiles directly from the OpenStreetMap tile servers (`tile.openstreetmap.org`), on venue pages with coordinates and on the venue editor screen in wp-admin. This transmits the IP address and the requested map section to OpenStreetMap. As a fallback for visitors without JavaScript, an embedded map from `openstreetmap.org` may be displayed. No tracking, analytics or usage data is collected by the plugin or sent anywhere.
Terms/attribution: https://www.openstreetmap.org/copyright – Privacy policy: https://wiki.osmfoundation.org/wiki/Privacy_Policy

**Nominatim geocoding (OpenStreetMap) (optional, disabled by default)** – Part of the same opt-in: only when the map provider "OpenStreetMap" is enabled, and only when an editor clicks the "Determine coordinates from address" button in the venue editor, the address typed into the form is sent to the Nominatim service (`nominatim.openstreetmap.org`) to look up coordinates. It is never called on the public website, and it is not called at all while maps are disabled.
Usage policy: https://operations.osmfoundation.org/policies/nominatim/ – Privacy policy: https://wiki.osmfoundation.org/wiki/Privacy_Policy

**Cloudflare Turnstile (optional, disabled by default)** – Only if an administrator enables Turnstile in the settings, the plugin loads the Turnstile widget script from Cloudflare (`challenges.cloudflare.com`) on pages that show a trainer contact form, and on submission sends the challenge token together with the visitor's IP address to Cloudflare for bot verification. When Turnstile is disabled, no data is sent to Cloudflare.
Terms of use: https://www.cloudflare.com/website-terms/ – Privacy policy: https://www.cloudflare.com/privacypolicy/

== Source code and build ==

The plugin ships with the complete, human-readable source of every generated file, plus the tooling needed to regenerate it. Nothing is obfuscated.

**Editor blocks** – `build/<block>/index.js` is generated and minified. The readable ES module source of each of these files is included in the plugin under `blocks/<block>/index.js` (same folder name, e.g. `blocks/kalender/index.js` → `build/kalender/index.js`).

Build tooling: [@wordpress/scripts](https://www.npmjs.com/package/@wordpress/scripts) (webpack + Babel), declared in the bundled `package.json` / `package-lock.json`. To regenerate the files from the shipped sources, run inside the plugin folder:

`npm ci`
`npm run build`

which executes `wp-scripts build --webpack-src-dir=blocks` and writes `build/`.

**PHP** – All PHP is plain, unminified source under `src/` (PSR-4, autoloaded via Composer; see the bundled `composer.json` / `composer.lock`). `assets/js/*.js` and `assets/css/*.css` are hand-written and unminified as well.

**Third-party libraries**

* Leaflet 1.9.4 – interactive maps, BSD-2-Clause. Bundled locally in `assets/vendor/leaflet/` (upstream distribution build, including `LICENSE`); it is never loaded from a CDN. Project and full source: https://github.com/Leaflet/Leaflet – release used: https://github.com/Leaflet/Leaflet/releases/tag/v1.9.4

== Installation ==

1. Copy the `squadeno-club-sports-manager` folder into `wp-content/plugins/` (or upload the plugin ZIP).
2. Activate it under "Plugins" in the WordPress admin. This creates the content types, roles and default seasons.
3. Maintain sports, trainers, venues and events under the new menu entries.
4. Create pages with the shortcodes or blocks (overview, calendar).
5. Optional: adjust the URL bases (slugs) in the plugin settings, then open Settings → Permalinks once to refresh the links.

== Frequently Asked Questions ==

= Can trainers maintain their own content? =
Yes. Trainers get a restricted role and edit only the sports assigned to them as well as their own profile.

= How are holidays handled? =
Central closures automatically hide regular trainings within the period; events (e.g. holiday care) remain visible.

= Is the plugin compatible with caching plugins? =
Yes. Dates are cached internally and invalidated whenever something changes, so a page or object cache on top only makes it faster.

= In which languages is the plugin available? =
The interface is English by default and ships with a complete German translation (de_DE). Additional languages can be added via the bundled .pot file.

= Can the URLs be in another language? =
Yes. The URL bases (e.g. `sports`, `trainers`) default to English and can be changed per site in the plugin settings, for example to German (`sportarten`, `trainer`). After changing them, open Settings → Permalinks once.

== Screenshots ==

1. All sports at a glance on the website, with filters for age group and section.
2. A sport's own page: training times, contacts and the automatically generated upcoming dates – holidays are blocked automatically.
3. The club-wide calendar (month or week view) with trainings, events and closures.
4. The admin overview introduces new users to the plugin and where to maintain content.
5. Guided setup in five steps.
6. Roles and permissions explained, including the three trainer permission levels.

== Changelog ==

= 1.9.0 =
* New calendar view `view="list"`: the training schedule of the week, grouped by weekday.
* Sub-categories in the calendar now name their main category, for example Gymnastics > Kids gymnastics.
* Settings: pick which calendar views the site offers (month, week, list).
* Cancelled dates in the training schedule are struck through instead of carrying a label.
* Admin area: closures, seasons, sections, age groups and event types moved into one menu entry "Base data" with tabs.
* The plugin directory page now offers a live preview: try the plugin with demo data, right in the browser.

= 1.8.1 =
* Clearer wording on the plugin directory page, with a link to the project page.
* German translation of the directory page, in both the informal and the formal address.
* No changes to the plugin itself.

= 1.8.0 =
* First public release in the WordPress plugin directory.

== Upgrade Notice ==

= 1.9.0 =
The calendar gains a training schedule view, and the admin menu has fewer entries. Existing pages, shortcodes and blocks keep working unchanged.

= 1.8.1 =
Text only: the directory page reads better and is now available in German. Nothing changes in the plugin, so there is no hurry.
