Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,17 @@
/.project
/.settings
/.classpath
/src/main/webapp/frontend-es6
/src/main/webapp/frontend-es5
node_modules

# IDE
/.vscode/

# Vaadin — generated / auto-scaffolded on build (regenerated, not source)
/src/main/frontend/
/src/main/bundles/
package.json
package-lock.json
tsconfig.json
types.d.ts
vite.config.ts
vite.generated.ts
202 changes: 202 additions & 0 deletions MIGRATION_PLAN.md

Large diffs are not rendered by default.

55 changes: 46 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,53 @@
# Demo Application: World Cup Rusia 2018 stats
# Demo Application: Global Football 2026 Stats

This project is a demo application that displays statistical data from the Football World Cup that is taking place in Russia
A demo application that displays the fixture and results of the **2026 international football
tournament** (Canada / USA / Mexico): match schedule, live scores, group standings and
per-country fixtures.

Import the project to the IDE of your choosing as a Maven project.
It is the modernized version of the original 2018 demo, migrated from Vaadin 10 to **Vaadin 25**.
See [MIGRATION_PLAN.md](MIGRATION_PLAN.md) for the full upgrade story.

Run application using
`mvn spring-boot:run`
## Tech stack

Open http://localhost:8080/ in browser
- **Vaadin 25.1.7** (Lit / npm frontend, plain-CSS theming via `@StyleSheet`)
- **Spring Boot 4.0.6**, **Java 21**, executable-jar packaging
- **Flowing Code AppLayout add-on** for the navigation shell
- **Caffeine** for short-lived response caching

For more information regarding this application, refer to [this blog post](https://www.flowingcode.com/2018/07/vaadin-10-spring-demo-application-world.html).
## Data source

For more information on Vaadin Flow, visit https://vaadin.com/flow.
Data comes from the free, no-API-key **[worldcup26.ir](https://worldcup26.ir/)** REST API
(teams, groups/standings, games, stadiums). Because it is a free source, rich per-match
statistics (lineups, possession, cards) are not available — the app shows fixtures, scores,
goal scorers and group standings. Live scores update during matches.

This demo is hosted at http://worldcup.flowingcode.com/
## Running

Development mode (hot reload):

```
mvn spring-boot:run
```

Then open <http://localhost:8080>.

Production build (compiles the optimized frontend bundle and a runnable jar):

```
mvn -Pproduction package
java -jar target/worldcup-fixture-2.0.0-SNAPSHOT.jar
```

## More information

For more information on Vaadin Flow, visit <https://vaadin.com/flow>.

## Disclaimer

Unofficial demo application. Not affiliated with, endorsed by, or sponsored by FIFA or any
football governing body. All team and tournament data comes from the public
[worldcup26.ir](https://worldcup26.ir/) API.

## Author

Developed by [Flowing Code](https://www.flowingcode.com).
166 changes: 49 additions & 117 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,42 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.flowingcode.fixture</groupId>
<artifactId>worldcup-fixture</artifactId>
<name>World Cup Fixture in Vaadin 10</name>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>World Cup Stats in Vaadin 25</name>
<version>2.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.6</version>
<relativePath/>
</parent>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>

<webapp.directory>src/main/webapp</webapp.directory>

<!-- Dependencies -->
<vaadin.version>10.0.1</vaadin.version>
<spring-boot.version>2.0.2.RELEASE</spring-boot.version>
<vaadin.version>25.1.7</vaadin.version>
<app-layout-addon.version>6.2.0-SNAPSHOT</app-layout-addon.version>
</properties>

<pluginRepositories>
<pluginRepository>
<id>vaadin-prereleases</id>
<url>https://maven.vaadin.com/vaadin-prereleases</url>
</pluginRepository>
</pluginRepositories>

<repositories>
<repository>
<id>vaadin-prereleases</id>
<url>https://maven.vaadin.com/vaadin-prereleases</url>
<id>Vaadin Directory</id>
<url>https://maven.vaadin.com/vaadin-addons</url>
</repository>
<repository>
<id>Vaadin Directory</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
<id>FlowingCode Snapshots</id>
<url>https://maven.flowingcode.com/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>

<dependencyManagement>
Expand All @@ -49,123 +51,64 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
<version>${vaadin.version}</version>
</dependency>


<!-- Vaadin dev server (dev mode only); ignored in production mode. -->
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring</artifactId>
<artifactId>vaadin-dev</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>


<!-- Flowing Code AppLayout add-on (Vaadin 25 compatible) -->
<dependency>
<groupId>com.flowingcode.addons.applayout</groupId>
<artifactId>app-layout-addon</artifactId>
<version>1.0.1</version>
<groupId>com.flowingcode.addons.applayout</groupId>
<artifactId>app-layout-addon</artifactId>
<version>${app-layout-addon.version}</version>
</dependency>


<!-- Caching: Caffeine (replaces ehcache 3.x; supports TTL via spec) -->
<dependency>
<groupId>org.webjars.bowergithub.polymerelements</groupId>
<artifactId>marked-element</artifactId>
<version>2.4.0</version>
</dependency>

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.5.2</version>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<packagingExcludes>
%regex[WEB-INF/lib/slf4j-simple.*.jar],
%regex[WEB-INF/lib/tomcat.*.jar]
</packagingExcludes>
</configuration>
</plugin>


<plugin>
<groupId>com.heroku.sdk</groupId>
<artifactId>heroku-maven-plugin</artifactId>
<version>2.0.4</version>
<configuration>
<appName>worldcup-staging</appName>
</configuration>
</plugin>

</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<filesets>
<fileset>
<directory>${webapp.directory}/frontend-es5</directory>
</fileset>
<fileset>
<directory>${webapp.directory}/frontend-es6</directory>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>productionMode</id>
<activation>
<property>
<name>vaadin.productionMode</name>
</property>
</activation>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-server-production-mode</artifactId>
</dependency>
</dependencies>

<id>production</id>
<build>
<plugins>
<plugin>
Expand All @@ -175,24 +118,13 @@
<executions>
<execution>
<goals>
<goal>copy-production-files</goal>
<goal>package-for-production</goal>
<goal>prepare-frontend</goal>
<goal>build-frontend</goal>
</goals>
<configuration>
<transpileOutputDirectory>${webapp.directory}</transpileOutputDirectory>
</configuration>
<phase>compile</phase>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<jvmArguments>-Dvaadin.productionMode</jvmArguments>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Expand Down
29 changes: 20 additions & 9 deletions src/main/java/com/flowingcode/fixture/FixtureApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,41 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

import com.vaadin.flow.component.dependency.StyleSheet;
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.component.page.Push;
import com.vaadin.flow.component.page.Viewport;
import com.vaadin.flow.server.AppShellSettings;
import com.vaadin.flow.theme.lumo.Lumo;

/**
* The entry point of the Spring Boot application.
* The entry point of the Spring Boot application. Also acts as the Vaadin
* application shell: in Vaadin 25 all app-shell annotations ({@code @Push},
* {@code @Viewport}) and stylesheet loading must live on the single
* {@link AppShellConfigurator}. Theming is done with plain CSS loaded via
* {@code @StyleSheet} (the {@code @Theme} annotation is deprecated in 25).
*/
@SpringBootApplication
@EnableCaching
@EnableScheduling
@Configuration
public class FixtureApp extends SpringBootServletInitializer {
@Push
@Viewport("width=device-width, initial-scale=1.0")
@StyleSheet(Lumo.STYLESHEET)
@StyleSheet("styles.css")
public class FixtureApp implements AppShellConfigurator {

public static void main(final String[] args) {
SpringApplication.run(FixtureApp.class, args);
}

@Override
protected SpringApplicationBuilder configure(
final SpringApplicationBuilder builder) {
return builder.sources(FixtureApp.class);
public void configurePage(final AppShellSettings settings) {
settings.addFavIcon("icon", "/frontend/images/favicons/favicon-96x96.png", "96x96");
settings.addLink("shortcut icon", "/frontend/images/favicons/favicon-96x96.png");
}

@Bean
Expand Down

This file was deleted.

Loading