Compare commits

..

11 Commits

Author SHA1 Message Date
jadera a3ab778a84 uskomaton säätö 2025-12-10 21:10:56 +02:00
jadera 4de56eef0b vitttttttuuuu 2025-12-10 20:51:29 +02:00
jadera b3eae06a5b vithu 2025-12-10 20:43:27 +02:00
jadera f8a711a869 vittu 2025-12-10 20:33:05 +02:00
jadera 19fbe71506 switch to testcafe image 2025-12-10 20:25:43 +02:00
jadera 469f4f4da6 chown test files to runner 2025-12-10 20:14:06 +02:00
jadera cd2a58a76d testcafe testing 2025-12-10 20:04:40 +02:00
jadera 84b2b450c6 drop testcafe node back to 16 2025-12-10 19:46:42 +02:00
jadera 7d3fd6857c fix crossfade from legacy 2025-12-10 19:38:18 +02:00
jadera 9f44bf57f6 node bump 16->20 2025-12-10 19:27:47 +02:00
jadera 9d9211fa9c testing version bumps
extras

kakka
2025-12-10 19:21:50 +02:00
44 changed files with 34131 additions and 28242 deletions
+1
View File
@@ -5,3 +5,4 @@ node_modules
# don't lint nyc coverage output
coverage
next-env.d.ts
tests
+17 -8
View File
@@ -8,7 +8,7 @@ stages:
- deploy
install:
image: node:16
image: node:20
stage: setup
script:
- npm ci
@@ -21,7 +21,7 @@ install:
expire_in: 1 week
audit:
image: node:16
image: node:20
needs: ["install"]
allow_failure: true
stage: audit
@@ -29,27 +29,27 @@ audit:
- npm audit --audit-level=critical
es:lint:
image: node:16
image: node:20
needs: ["install"]
stage: lint
script:
- npm run lint:es
css:lint:
image: node:16
image: node:20
needs: ["install"]
stage: lint
script:
- npm run lint:css
# test:unit:
# image: node:16
# image: node:20
# stage: test
# script:
# - npm run test:unit
build:
image: node:16
image: node:20
needs: ["install"]
stage: build
script:
@@ -67,11 +67,20 @@ build:
- .next/cache/
test:e2e:
image: circleci/node:16-browsers
# Use a Cypress image which has Node 20 + Chrome and runs as root (solves permission issues)
image: cypress/browsers:latest
needs: ["install", "build"]
stage: test
script:
- npm run testcafe
# No sudo needed if running as root.
# If permissions are still wrong, we CAN fix them because we are root.
# But usually, being root means we can overwrite/rm the files anyway.
# 1. Clean install to ensure native modules match this container's environment
- npm ci
# 2. Run TestCafe (using the CI script for headless mode)
- npm run testcafe:ci
artifacts:
paths:
- e2e-screenshots
+2 -1
View File
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
+46 -21
View File
@@ -1,29 +1,54 @@
// web2.0-frontend/next.config.js
const { withSentryConfig } = require("@sentry/nextjs");
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
const sentryWebpackPluginOptions = {
// Additional config options for the Sentry Webpack plugin. Keep in mind that
// the following options are set automatically, and overriding them is not
// recommended:
// release, url, org, project, authToken, configFile, stripPrefix,
// urlPrefix, include, ignore
silent: true, // Suppresses all logs
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options.
};
module.exports = withBundleAnalyzer(withSentryConfig({
/** @type {import('next').NextConfig} */
const nextConfig = {
compiler: {
styledComponents: true,
},
images: {
domains: [
"api.sahkoinsinoorikilta.fi",
"static.sahkoinsinoorikilta.fi",
"api.dev.sahkoinsinoorikilta.fi",
remotePatterns: [
{
protocol: "https",
hostname: "api.sahkoinsinoorikilta.fi",
},
{
protocol: "https",
hostname: "static.sahkoinsinoorikilta.fi",
},
{
protocol: "https",
hostname: "api.dev.sahkoinsinoorikilta.fi",
},
],
},
sentry: {
hideSourceMaps: true, // Hide source maps, see: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-source-maps
},
}, sentryWebpackPluginOptions));
// Note: The 'sentry' key is removed from here as it is no longer supported in v8
};
// Sentry options are now passed as a single object in the second argument
const sentryOptions = {
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options
// Suppresses all logs
silent: true,
// Hides source maps from generated client bundles
hideSourceMaps: true,
// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
// (Optional) You can add org and project if not set in environment variables
// org: "your-org-slug",
// project: "your-project-slug",
};
// Wrap the config with Sentry first, then Bundle Analyzer
module.exports = withBundleAnalyzer(withSentryConfig(nextConfig, sentryOptions));
+14642 -8619
View File
File diff suppressed because it is too large Load Diff
+16 -15
View File
@@ -20,21 +20,22 @@
"postbuild": "next-sitemap",
"export": "next export",
"lint": "npm run lint:es && npm run lint:css",
"lint:es": "next lint",
"lint:es:fix": "next lint --fix",
"lint:es": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:es:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
"lint:css": "stylelint \"./src/**/*.{ts,tsx}\"",
"dev": "next dev",
"start": "next dev",
"dev": "next dev --webpack",
"start": "next dev --webpack",
"start-prod": "next start --port ${SERVER_PORT:=80}",
"serve": "next start --port 3000",
"test:unit": "jest --coverage",
"test": "npm run testcafe",
"testcafe": "testcafe --config-file testcafe.json",
"testcafe:ci": "testcafe 'chrome:headless --no-sandbox --disable-dev-shm-usage' --config-file testcafe.json",
"build-analyze": "ANALYZE=true npm run build",
"prepare": "husky install"
},
"devDependencies": {
"@types/jest": "^27.4.1",
"@types/jest": "^30.0.0",
"@types/js-cookie": "^3.0.1",
"@types/node": "^16.11.36",
"@types/react": "^18.0.15",
@@ -45,13 +46,13 @@
"@typescript-eslint/eslint-plugin": "^5.18.0",
"@typescript-eslint/parser": "^5.18.0",
"babel-plugin-styled-components": "^2.0.7",
"eslint": "^8.13.0",
"eslint": "^8.57.1",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-next": "^13.1.6",
"eslint-config-next": "^13.5.11",
"eslint-plugin-import": "^2.26.0",
"husky": "^7.0.4",
"jest": "^27.5.1",
"jest": "^30.2.0",
"next-sitemap": "^3.1.11",
"npm-run-all": "^4.1.5",
"postcss-jsx": "^0.36.4",
@@ -59,21 +60,21 @@
"stylelint": "^14.2.0",
"stylelint-config-recommended": "^6.0.0",
"stylelint-config-styled-components": "^0.1.1",
"testcafe": "^1.18.5",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3"
"testcafe": "^3.7.2",
"ts-jest": "^29.4.6",
"typescript": "^5.9.3"
},
"dependencies": {
"@next/bundle-analyzer": "^12.2.3",
"@rjsf/core": "^4.2.0",
"@sentry/nextjs": "^7.34.0",
"axios": "^0.26.1",
"@sentry/nextjs": "^10.29.0",
"axios": "^1.13.2",
"date-fns": "^2.28.0",
"fast-deep-equal": "^3.1.3",
"js-cookie": "^3.0.1",
"lodash": "^4.17.21",
"mqtt": "^5.14.1",
"next": "^13.1.6",
"next": "^16.0.8",
"normalize.css": "^8.0.1",
"react": "^18.2.0",
"react-csv": "^2.2.2",
@@ -87,7 +88,7 @@
"react-toastify": "^9.0.7",
"rehype-raw": "^6.1.1",
"rehype-sanitize": "^5.0.1",
"sharp": "^0.30.3",
"sharp": "^0.34.5",
"shortid": "^2.2.16",
"styled-components": "^5.3.5",
"swr": "^1.2.2",
+18
View File
@@ -0,0 +1,18 @@
// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).
// The config you add here will be used whenever one of the edge features is loaded.
// Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from "@sentry/nextjs";
const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
const ENV = process.env.NEXT_PUBLIC_DEPLOY_ENV;
Sentry.init({
dsn: SENTRY_DSN,
environment: ENV,
// Adjust this value in production, or use tracesSampler for greater control
// tracesSampleRate: 1.0, // Commented out as client/server configs don't have it
// Setting this option to true will print useful information to the console while you're setting up Sentry.
// debug: false, // Commented out as client/server configs don't have it
});
+1 -1
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
const Icon = "/img/add-icon.png";
+3 -2
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import colors from "@theme/colors";
import Link from "@components/Link";
@@ -22,6 +22,7 @@ const StyledCard = styled.article`
display: flex;
flex-direction: column;
color: ${colors.black};
position: relative;
margin: 1rem;
text-align: center;
@@ -72,7 +73,7 @@ const WrappedCard: React.FC<WrappedCardProps> = ({
}) => (
<StyledCard {...props}>
{image && (
<Image src={image.src} alt={image.alt} layout="responsive" width={0} height={0} objectFit="scale-down" />
<Image src={image.src} alt={image.alt} fill sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" style={{ objectFit: "scale-down" }} />
)}
<p>{startTime}</p>
<h3>{title}</h3>
+4 -3
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import colors from "@theme/colors";
@@ -73,8 +73,9 @@ const ContactCard: React.FC<ContactCardProps> = ({
<Image
src={image}
alt={name}
layout="fill"
objectFit="cover"
fill
sizes="128px"
style={{ objectFit: "cover" }}
/>
</ImageContainer>
) : null}
+8 -7
View File
@@ -1,16 +1,16 @@
import React from "react";
import Image, { ImageProps } from "next/legacy/image";
import Image from "next/image";
import styled, { keyframes, Keyframes } from "styled-components";
interface CrossFadeImagesProps {
width: ImageProps["width"];
height: ImageProps["height"];
width: number | string;
height: number | string;
images: string[];
presentationTime: number;
fadeTime: number;
}
const AnimatedImage = styled(Image)<{ layout: string; $delay: number }>`
const AnimatedImage = styled(Image) <{ $delay: number }>`
animation-delay: ${(p) => p.$delay}s;
`;
@@ -69,14 +69,15 @@ const CrossFadeImages: React.FC<CrossFadeImagesProps> = ({
$animation={animation}
$duration={len * SINGLE_IMAGE_TIME}
>
{ images.map((image, idx) => (
{images.map((image, idx) => (
// eslint-disable-next-line react/no-array-index-key
<div key={idx} className={idx > 0 ? "not-first" : undefined}>
<AnimatedImage
src={image}
objectFit="cover"
width={width}
height={height}
alt=""
width={width as any}
height={height as any}
layout="responsive"
$delay={delays[idx]}
/>
+4 -3
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import { Link } from "@components/index";
@@ -18,8 +18,9 @@ const HeaderLogo: React.FC = () => (
<Image
src={TitleImage}
alt="logo"
layout="fill"
objectFit="scale-down"
fill
sizes="200px"
style={{ objectFit: "scale-down" }}
/>
</Logo>
);
+20 -10
View File
@@ -1,5 +1,5 @@
import React, {
createContext, useContext, useMemo, useReducer,
createContext, useContext, useMemo, useReducer, useEffect,
} from "react";
import fi from "./locales/fi/common.json";
import en from "./locales/en/common.json";
@@ -36,16 +36,10 @@ interface Store {
changeLanguage: React.Dispatch<Lang>,
}
let initialLanguage: Lang = "fi";
try {
const storedLang = localStorage.getItem(LOCAL_STORAGE_KEY) as Lang;
initialLanguage = storedLang;
} catch (err) {
// Just ignore if fails to get value from browser (server etc.)
}
// Always default to 'fi' for the initial state to ensure Server/Client match.
// We will hydrate the user's preference in useEffect below.
const initialState: Store = {
language: initialLanguage,
language: "fi",
changeLanguage: null,
};
@@ -69,6 +63,22 @@ const Reducer = (state: Store, action: Lang) => {
const LocaleContext = createContext(initialState);
const LocaleStore: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(Reducer, initialState);
// Sync with localStorage only after the component has mounted (client-side)
useEffect(() => {
try {
const storedLang = localStorage.getItem(LOCAL_STORAGE_KEY) as Lang;
if (storedLang && (storedLang === "fi" || storedLang === "en")) {
// Only dispatch if different to prevent unnecessary re-renders
if (storedLang !== state.language) {
dispatch(storedLang);
}
}
} catch (err) {
// Just ignore if fails to get value from browser
}
}, []); // Empty dependency array ensures this runs once on mount
const changeLanguage = (action: Lang) => {
dispatch(action);
try {
@@ -1,7 +1,4 @@
// This file configures the initialization of Sentry on the browser.
// The config you add here will be used whenever a page is visited.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
/* eslint-disable import/prefer-default-export */
import * as Sentry from "@sentry/nextjs";
const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
@@ -14,3 +11,6 @@ Sentry.init({
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
// that it will also get attached to your source maps
});
// This is required by Sentry v8 to instrument navigation (tracing)
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
+13
View File
@@ -0,0 +1,13 @@
import * as Sentry from "@sentry/nextjs";
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
await import("../sentry.server.config");
}
if (process.env.NEXT_RUNTIME === "edge") {
await import("../sentry.edge.config");
}
}
export const onRequestError = Sentry.captureRequestError;
+39 -39
View File
@@ -8,10 +8,10 @@
"name_en": "Chairman of the Board",
"representatives": [
{
"name": "Sauli Hakala",
"name": "Emma Uusküla",
"phone_number": null,
"email": "sauli.hakala@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/sauli.jpg"
"email": "emma.uuskula@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Emma.jpg"
}
]
},
@@ -20,10 +20,10 @@
"name_en": "Vice Chair",
"representatives": [
{
"name": "Eemeli Hintsanen",
"name": "Johannes Viirimäki",
"phone_number": null,
"email": "eemeli.hintsanen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/eemeli.jpg"
"email": "johannes.viirimaki@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Johannes.jpg"
}
]
},
@@ -32,10 +32,10 @@
"name_en": "Treasurer",
"representatives": [
{
"name": "Nea Kanerva",
"name": "Nelli Liljasto",
"phone_number": null,
"email": "nea.kanerva@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/nea.jpg"
"email": "nelli.liljasto@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Nelli.jpg"
}
]
},
@@ -44,10 +44,10 @@
"name_en": "",
"representatives": [
{
"name": "Aura Friman",
"name": "Teemu Heikkinen",
"phone_number": null,
"email": "aura.friman@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/aura.jpg"
"email": "teemu.heikkinen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Teemu.jpg"
}
]
},
@@ -56,10 +56,10 @@
"name_en": "",
"representatives": [
{
"name": "Antti Salpakari",
"name": "Henri Aito",
"phone_number": null,
"email": "antti.salpakari@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/antti.jpg"
"email": "henri.aito@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Henri.jpg"
}
]
},
@@ -68,10 +68,10 @@
"name_en": "",
"representatives": [
{
"name": "Aino Saarela",
"name": "Tuomas Rantamäki",
"phone_number": null,
"email": "aino.saarela@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/aino_sa.jpg"
"email": "tuomas.rantamaki@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/TuomasR.jpg"
}
]
},
@@ -80,10 +80,10 @@
"name_en": "",
"representatives": [
{
"name": "Rosanna Reims",
"name": "Matilda Ahonen",
"phone_number": null,
"email": "rosanna.reims@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/rosanna.jpg"
"email": "matilda.ahonen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Matilda.jpg"
}
]
},
@@ -92,10 +92,10 @@
"name_en": "",
"representatives": [
{
"name": "Valentin Juhela",
"name": "Niklas Ritalahti",
"phone_number": null,
"email": "valentin.juhela@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/valentin.jpg"
"email": "niklas.ritalahti@sahkoinsinoorikilta.fi",
"image": ""
}
]
},
@@ -104,10 +104,10 @@
"name_en": "",
"representatives": [
{
"name": "Elida Widgren",
"name": "Mikael Vatiainen",
"phone_number": null,
"email": "elida.widgren@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/elida.jpg"
"email": "mikael.vatiainen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Mikael.jpg"
}
]
},
@@ -116,10 +116,10 @@
"name_en": "",
"representatives": [
{
"name": "Joona Maaranen",
"name": "Simeon Pursiainen",
"phone_number": null,
"email": "joona.maaranen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/joona.jpg"
"email": "simeon.pursiainen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Simeon.jpg"
}
]
},
@@ -128,10 +128,10 @@
"name_en": "",
"representatives": [
{
"name": "Jere Oinonen",
"name": "Markus Aaltio",
"phone_number": null,
"email": "jere.oinonen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/jere.jpg"
"email": "markus.aaltio@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Markus.jpg"
}
]
},
@@ -140,10 +140,10 @@
"name_en": "",
"representatives": [
{
"name": "Into Saarinen",
"name": "Tuomas Hintikka",
"phone_number": null,
"email": "into.saarinen@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/into.jpg"
"email": "tuomas.hintikka@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/TuomasH.jpg"
}
]
},
@@ -152,10 +152,10 @@
"name_en": "",
"representatives": [
{
"name": "Aino Svahn",
"name": "Yassine Ramid",
"phone_number": null,
"email": "aino.svahn@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/2026/aino_sv.jpg"
"email": "yassine.ramid@sahkoinsinoorikilta.fi",
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Yassine.jpg"
}
]
}
@@ -16,9 +16,6 @@ import YtmkJson from "./ytmk.json";
import SwtmkJson from "./swtmk.json";
import VtmkJson from "./vtmk.json";
import LtmkJson from "./ltmk.json";
import SiccJson from "./sicc.json";
import SptmkJson from "./sptmk.json";
import PotatmkJson from "./potatmk.json"
import Others from "./others.json";
const orderedCommittees = [
@@ -34,9 +31,6 @@ const orderedCommittees = [
VtmkJson,
SwtmkJson,
NtmkJson,
SiccJson,
SptmkJson,
PotatmkJson,
Others,
];
+6 -6
View File
@@ -9,7 +9,7 @@
"name_en": "",
"representatives": [
{
"name": "Aura Friman"
"name": "Teemu Heikkinen"
}
]
},
@@ -18,7 +18,7 @@
"name_en": "",
"representatives": [
{
"name": "Antti Salpakari"
"name": "Henri Aito"
}
]
},
@@ -27,10 +27,10 @@
"name_en": "International Fuksi Captain",
"representatives": [
{
"name": "Jere Oinonen"
"name": "Markus Aaltio"
},
{
"name": "Hocine Montenez"
"name": "Apollo Ailus"
}
]
},
@@ -39,7 +39,7 @@
"name_en": "Tutor Coordinator",
"representatives": [
{
"name": "Veera Lindroos"
"name": "Axel Aurola"
}
]
},
@@ -48,7 +48,7 @@
"name_en": "International Tutor Coordinator",
"representatives": [
{
"name": "Janne Yrjölä"
"name": "Igor Oinonen"
}
]
}
+10 -13
View File
@@ -9,7 +9,7 @@
"name_en": "Master of Ceremonies",
"representatives": [
{
"name": "Aino Saarela"
"name": "Tuomas Rantamäki"
}
]
},
@@ -18,7 +18,7 @@
"name_en": "Court Counsellor",
"representatives": [
{
"name": "Rosanna Reims"
"name": "Matilda Ahonen"
}
]
},
@@ -27,13 +27,16 @@
"name_en": "Hostess",
"representatives": [
{
"name": "Elina Pyylampi"
"name": "Veera Lindroos"
},
{
"name": "Elle Leivo"
"name": "Aino Saarela"
},
{
"name": "Emma Salmenaho"
"name": "Nea Kanerva"
},
{
"name": "Rosanna Reims"
}
]
},
@@ -42,16 +45,10 @@
"name_en": "Host",
"representatives": [
{
"name": "Aleksi Nuutinen"
"name": "Eemeli Hintsanen"
},
{
"name": "Juho Rosnell"
},
{
"name": "Julius Härkönen"
},
{
"name": "Joonas Hilvo"
"name": "André Palosaari"
}
]
}
+22 -24
View File
@@ -9,7 +9,7 @@
"name_en": "Master of Wellbeing",
"representatives": [
{
"name": "Valentin Juhela"
"name": "Niklas Ritalahti"
}
]
},
@@ -18,13 +18,22 @@
"name_en": "Culture Representative",
"representatives": [
{
"name": "Johannes Viirimäki"
"name": "Peter Lindahl"
},
{
"name": "Linnea Viitasalo"
"name": "Kuura Janhunen"
},
{
"name": "Matilda Ahonen"
"name": "Valentin Juhela"
},
{
"name": "Leevi Leinonen"
},
{
"name": "Milla Heino"
},
{
"name": "Hocine Montenez"
}
]
},
@@ -33,13 +42,10 @@
"name_en": "Sports Representative",
"representatives": [
{
"name": "Aino Salmi"
"name": "Matias Hendolin"
},
{
"name": "Eeda Alasaari"
},
{
"name": "Iiris Kuulusa"
"name": "Sauli Hakala"
}
]
},
@@ -51,7 +57,7 @@
"name": "Milja Kuusela"
},
{
"name": "Tuomas Rantamäki"
"name": "Aaro Rasilainen"
}
]
},
@@ -60,17 +66,15 @@
"name_en": "",
"representatives": [
{
"name": "Arvi Virkkunen"
"name": "Tommi Sytelä"
},
{
"name": "Auli Purolinna"
"name": "Konsta Hakala"
},
{
"name": "Ville Lairila"
},
{
"name": "Tiitus Koski"
}
]
},
{
@@ -78,22 +82,16 @@
"name_en": "",
"representatives": [
{
"name": "Teemu Heikkinen"
"name": "Saara Rossi"
},
{
"name": "Aaron Löfgren"
},
{
"name": "Matilda Ahonen"
}
]
"name": "Milla Heino"
},
{
"name_fi": "Kiltamuori",
"name_en": "",
"representatives": [
{
"name": "Markus Aaltio"
"name": "Sauli Hakala"
}
]
}
+12 -15
View File
@@ -9,7 +9,7 @@
"name_en": "",
"representatives": [
{
"name": "Aino Salmi"
"name": "Leevi Oikarinen"
}
]
},
@@ -18,16 +18,19 @@
"name_en": "",
"representatives": [
{
"name": "Alex Hyytinen"
"name": "Aino Salmi"
},
{
"name": "Ilmari Reponen"
},
{
"name": "Iiris Kuulusa"
"name": "Jenni Marttinen"
},
{
"name": "Samuel Södervall"
"name": "Peter Lindahl"
},
{
"name": "Patrik Varteva"
},
{
"name": "Tapio Immonen"
@@ -39,25 +42,19 @@
"name_en": "",
"representatives": [
{
"name": "Aapo Palojärvi"
"name": "Alex Hyytinen"
},
{
"name": "André Palosaari"
"name": "Antti Salpakari"
},
{
"name": "Kaisa Lehtimäki"
"name": "Iiris Kuulusa"
},
{
"name": "Olav Hamel"
"name": "Roman Shalamov"
},
{
"name": "Otto Tuominen"
},
{
"name": "Panu Leinonen"
},
{
"name": "Terhi Lukkari"
"name": "Samuel Södervall"
}
]
}
+27 -33
View File
@@ -9,7 +9,7 @@
"name_en": "Editor in Chief",
"representatives": [
{
"name": "Joona Komonen",
"name": "Topi Manskinen",
"phone_number": null,
"email": null,
"image": null
@@ -21,7 +21,7 @@
"name_en": "",
"representatives": [
{
"name": "Topi Manskinen",
"name": "Visa Kurvi",
"phone_number": null,
"email": null,
"image": null
@@ -33,34 +33,31 @@
"name_en": "Journalist",
"representatives": [
{
"name": "Aake Laukkanen"
"name": "Joona Komonen"
},
{
"name": "Alex Hyytinen"
},
{
"name": "Apollo Ailus"
},
{
"name": "Eetu Tossavainen"
"name": "Olli Vaismaa"
},
{
"name": "Jenni Marttinen"
},
{
"name": "Juho Laukka"
"name": "Ilmari Reponen"
},
{
"name": "Lauri Anttila"
"name": "Igor Oinonen"
},
{
"name": "Otto kievimaa"
"name": "Otto Kievimaa"
}
]
},
{
"name": "Sampo Haarala"
},
"name_fi": "Toimittaja, Taittaja",
"name_en": "",
"representatives": [
{
"name": "Venla Nikkanen"
"name": "Atte Vitie"
}
]
},
@@ -68,17 +65,8 @@
"name_fi": "Taittaja",
"name_en": "",
"representatives": [
{
"name": "Atte Vitie"
},
{
"name": "Lauri Anttila"
},
{
"name": "Otto Kievimaa"
},
{
"name": "Partrik Varteva"
}
]
},
@@ -86,23 +74,29 @@
"name_fi": "Graafikko",
"name_en": "Photographer & Graphic Artist",
"representatives": [
{
"name": "Annika Tattari"
},
{
"name": "Elian Salmimaa"
},
{
"name": "Lotta Kähönen"
}
]
},
{
"name_fi": "Heevistriimaaja",
"name_en": "Heevistreamer",
"name_fi": "Valokuvaaja",
"name_en": "Photographer",
"representatives": [
{
"name": "Veikko Räty"
},
{
"name": "Into Saarinen"
},
{
"name": "Aaro Rasilainen"
},
{
"name": "Anton Niemi"
},
{
"name": "Veera Melvasalo"
}
]
}
+52 -44
View File
@@ -5,20 +5,32 @@
"info": "N-toimikunta järjestää erinäisiä tapahtumia vanhemmille ja vanhemmanmielisille kiltalaisille, kuten sitsejä, aftereita, ulkoilutapahtumia ja mitä ikinä keksitäänkään. N-toimikunta toimii myös matalan kynnyksen välinä Sklubiin, eli alumniyhdistykseemme. N-toimikuntaan kuuluu myös killan kiltapatruunat, jotka pitävät huolta killan jatkuvuudesta.",
"roles": [
{
"name_fi": "N-toimikunnan puheenjohtaja",
"name_fi": "N-toimikunnan nestori",
"name_en": "",
"representatives": [
{
"name": "Elina Huttunen"
"name": "Karoliina Talvikangas"
}
]
},
{
"name_fi": "N-toimikunnan Varapuheenjohtaja",
"name_fi": "N-toimikunnan varanestori, Kiltapatruuna",
"name_en": "",
"representatives": [
{
"name": "Ville Lairila"
"name": "Aaron Löfgren"
}
]
},
{
"name_fi": "Sklubi-yhdyshenkilö",
"name_en": "",
"representatives": [
{
"name": "Melisa Dönmez"
},
{
"name": "Eveliina Ahonen"
}
]
},
@@ -27,61 +39,57 @@
"name_en": "",
"representatives": [
{
"name": "Aaron Löfgren"
"name": "Ville Lairila"
},
{
"name": "Visa Kurvi"
}
]
},
{
"name_fi":
"Kiltapatruuna, Nipsu",
"name_en": "",
"representatives": [
{
"name": "Mikko Sandström"
},
{
"name": "Liisa Haltia"
},
{
"name": "Elina Huttunen"
}
]
},
{
"name_fi": "Nipsu",
"name_en": "",
"representatives": [
{
"name": "Mikael Siikonen"
},
{
"name": "Axel Aurola"
},
{
"name": "Emma Uusküla"
},
{
"name": "Johannes Viirimäki"
},
{
"name": "Tuomas Rantamäki"
},
{
"name": "Yassine Ramid"
}
]
},
{
"name_fi": "N-vastaava",
"name_en": "",
"representatives": [
{
"name": "Aaron Löfgren"
},
{
"name": "Aleksi Saajakari"
},
{
"name": "Elian Salmimaa"
},
{
"name": "Johannes Viirimäki"
"name": "Elias Damski"
},
{
"name": "Karoliina Talvikangas"
"name": "Elias Lindberg"
},
{
"name": "Markus Aaltio"
},
{
"name": "Miika Helminen"
},
{
"name": "Mikael Siikonen"
},
{
"name": "Peter Lindahl"
},
{
"name": "Veikko Räty"
"name": "Eero Ketonen"
},
{
"name": "Verneri Turkki"
},
{
"name": "Akseli Heikkinen"
}
]
}
+5 -18
View File
@@ -9,7 +9,7 @@
"name_en": "Master of Studies",
"representatives": [
{
"name": "Elida Widgren"
"name": "Mikael Vatiainen"
}
]
},
@@ -18,36 +18,23 @@
"name_en": "Study Coordinator",
"representatives": [
{
"name": "Aapo Tynninen"
},
{
"name": "Aleksi Liukkonen"
"name": "Atu Vahla"
},
{
"name": "Antti Lehtonen"
},
{
"name": "Atu Vahla"
},
{
"name": "Iiris Kuulusa"
"name": "Aleksi Liukkonen"
},
{
"name": "Ilmari Reponen"
},
{
"name": "Jesper Seppäläinen"
"name": "Milla Heino"
},
{
"name": "Mikael Vatiainen"
},
{
"name": "Vi Tam"
},
{
"name": "Yassine Ramid"
"name": "Samuel Södervall"
}
]
}
]
+8 -28
View File
@@ -5,47 +5,27 @@
"info": "",
"roles": [
{
"name_fi": "Arkistovastaava",
"name_en": "",
"name_fi": "Merikapteeni",
"name_en": "Sea captain",
"representatives": [
{
"name": "Aaron Löfgren",
"name": "Ville Lairila",
"phone_number": null,
"email": null
}
]
},
{
"name_fi": "Sklubi-yhdyshenkilö",
"name_en": "",
"name_fi": "Meripojankloppi",
"name_en": "ship's boy",
"representatives": [
{
"name": "Ville Kurko",
"phone_number": null,
"email": null
}
]
},
{
"name_fi": "Teekkarikokousen kiltaedustaja",
"name_en": "",
"representatives": [
{
"name": "Aaron Löfgren",
"phone_number": null,
"email": null
}
]
},
{
"name_fi": "TEK-yhdyshenkilö",
"name_en": "",
"representatives": [
{
"name": "Visa Kurvi",
"name": "Peter Lindahl",
"phone_number": null,
"email": null
}
]
}
]
-83
View File
@@ -1,83 +0,0 @@
{
"slug": "potatmk",
"name_fi": "Potentiaalin Tasaus 105-toimikunta",
"name_en": "",
"info": "Killan vuosijuhlat",
"roles": [
{
"name_fi": "PoTa-tirehtööri",
"name_en": "",
"representatives": [
{
"name": "Axel Aurola"
},
{
"name": "Karoliina Talvikangas"
}
]
},
{
"name_fi": "Kukkohäntävastaava",
"name_en": "",
"representatives": [
{
"name": "Antti Salpakari"
},
{
"name": "Tuomas Rantamäki"
}
]
},
{
"name_fi": "Seremoniamestari",
"name_en": "",
"representatives": [
{
"name": "Henri Aito"
}
]
},
{
"name_fi": "Jatkovastaava",
"name_en": "",
"representatives": [
{
"name": "Aino Tasapuro"
},
{
"name": "Eemeli Hintsanen"
}
]
},
{
"name_fi": "Koristeluvastaava",
"name_en": "",
"representatives": [
{
"name": "Elina Huttunen"
}
]
},
{
"name_fi": "Sillisvastaava",
"name_en": "",
"representatives": [
{
"name": "Leevi Oikarinen"
},
{
"name": "Valentin Juhela"
}
]
},
{
"name_fi": "Graafikko",
"name_en": "",
"representatives": [
{
"name": "Elian Salmimaa"
}
]
}
]
}
+17 -20
View File
@@ -9,19 +9,7 @@
"name_en": "",
"representatives": [
{
"name": "Simeon Pursiainen"
}
]
},
{
"name_fi": "Pajavastaava",
"name_en": "",
"representatives": [
{
"name": "Axel Söderberg"
},
{
"name": "Đình Minh Trần"
"name": "Jere Oinonen"
}
]
},
@@ -30,25 +18,34 @@
"name_en": "",
"representatives": [
{
"name": "Aapo Tynninen"
"name": "Otto Kievimaa"
},
{
"name": "Aarni Kämppi"
"name": "Đình Minh Trần"
},
{
"name": "Atte Elo"
"name": "Valentin Juhela"
},
{
"name": "Emma Uusküla"
"name": "Axel Söderberg"
},
{
"name": "Jusi Seppälä"
"name": "Auli Purolinna"
},
{
"name": "Tuomas Rantamäki"
"name": "Karl Lipping"
},
{
"name": "Vi Tam"
"name": "Petrus Asikainen"
},
{
"name": "Elmo Kankkunen"
},
{
"name": "Samu Nyman"
},
{
"name": "Hilkka Gröhn"
}
]
}
-44
View File
@@ -1,44 +0,0 @@
{
"slug": "sicc",
"name_fi": "SIK International Committee Council",
"name_en": "SIK International Committee Council",
"info": "*coming soon*",
"roles": [
{
"name_fi": "International Ambassador",
"name_en": "International Ambassador",
"representatives": [
{
"name": "Igor Oinonen"
}
]
},
{
"name_fi": "International Attaché",
"name_en": "International Attaché",
"representatives": [
{
"name": "Kuura Janhunen"
}
]
},
{
"name_fi": "International Envoy",
"name_en": "International Envoy",
"representatives": [
{
"name": "Aleksanteri Vesala"
},
{
"name": "Apollo Ailus"
},
{
"name": "Juho Aikio"
},
{
"name": "Léo Di Poi"
}
]
}
]
}
-45
View File
@@ -1,45 +0,0 @@
{
"slug": "sptmk",
"name_fi": "Sähköpäivätoimikunta",
"name_en": "",
"info": "",
"roles": [
{
"name_fi": "Sähköpäivätirehtööri",
"name_en": "",
"representatives": [
{
"name": "Aino Tasapuro"
},
{
"name": "Matilda Ahonen"
}
]
},
{
"name_fi": "Sähköpäivävastaava",
"name_en": "",
"representatives": [
{
"name": "Aapo Nyyssönen"
},
{
"name": "Aapo Saranpää"
},
{
"name": "André Palosaari"
},
{
"name": "Ilmari Reponen"
},
{
"name": "Oliver Hannula"
},
{
"name": "Teemu Heikkinen"
}
]
}
]
}
+6 -15
View File
@@ -9,7 +9,7 @@
"name_en": "Head of sales",
"representatives": [
{
"name": "Leevi Oikarinen"
"name": "Tiitus Koski"
}
]
},
@@ -18,28 +18,19 @@
"name_en": "Clerk",
"representatives": [
{
"name": "Alexandr Lemin"
"name": "Arvi Virkkunen"
},
{
"name": "Henri Aito"
"name": "Valentin Juhela"
},
{
"name": "Ossi Jalkanen"
"name": "Otto Rinne"
},
{
"name": "Tiitus Koski"
"name": "Auli Purolinna"
},
{
"name": "Veikko Räty"
}
]
},
{
"name_fi": "Kiltapäiväkerhovastaava",
"name_en": "",
"representatives": [
{
"name": "Matilda Ahonen"
"name": "Patrik Varteva"
}
]
}
+8 -5
View File
@@ -9,7 +9,7 @@
"name_en": "Master of technology",
"representatives": [
{
"name": "Joona Maaranen"
"name": "Simeon Pursiainen"
}
]
},
@@ -18,16 +18,19 @@
"name_en": "",
"representatives": [
{
"name": "Alekdsandr Lemin"
"name": "Joona Maaranen"
},
{
"name": "Atte Elo"
"name": "Aleksi Liukkonen"
},
{
"name": "Dat Tram"
"name": "Elmo Kankkunen"
},
{
"name": "Oiva Haapaniemi"
"name": "Justus Ojala"
},
{
"name": "Tommi Sytelä"
}
]
}
+24 -38
View File
@@ -9,7 +9,7 @@
"name_en": "Head of communcations",
"representatives": [
{
"name": "Aino Svahn"
"name": "Yassine Ramid"
}
]
},
@@ -18,22 +18,25 @@
"name_en": "",
"representatives": [
{
"name": "Aada Tättilä"
"name": "Aaron Löfgren"
},
{
"name": "Ada Minkkinen"
"name": "Elina Huttunen"
},
{
"name": "Aino Tasapuro"
"name": "Aura Friman"
}
]
},
{
"name": "Ira Kosunen"
"name_fi": "Somevastaava, Brändivastaava",
"name_en": "",
"representatives": [
{
"name": "Aapo Saranpää"
},
{
"name": "Lukas Iles"
},
{
"name": "Tytti Solonen"
"name": "Aino Svahn"
}
]
},
@@ -42,15 +45,23 @@
"name_en": "",
"representatives": [
{
"name": "Aapo Saranpää"
"name": "Aleksandr Lemin"
},
{
"name": "Roope Jaskari"
},
{
"name": "Sauli Hakala"
},
{
"name": "Ville Lairila"
},
{
"name": "Aapo Nyyssönen"
},
{
"name": "Kehrä Halme"
"name": "Mikko Sandström"
}
]
},
{
@@ -58,37 +69,12 @@
"name_en": "",
"representatives": [
{
"name": "Apollo Ailus"
"name": "Veera Melvasalo"
},
{
"name": "Julius Männistö"
}
]
},
{
"name_fi": "Valokuvaaja",
"name_en": "",
"representatives": [
{
"name": "Aaro Rasilainen"
},
{
"name": "Apollo Ailus"
},
{
"name": "Arvi Virkkunen"
},
{
"name": "Julius Männistö"
},
{
"name": "Lotta Kähönen"
},
{
"name": "Veikko Räty"
}
]
}
]
}
+46 -16
View File
@@ -7,15 +7,6 @@
{
"name_fi": "Yrityssuhdemestari",
"name_en": "Head of Corporate Relations",
"representatives": [
{
"name": "Into Saarinen"
}
]
},
{
"name_fi": "Yrityssuhdeguru",
"name_en": "Guru of yritysuhde",
"representatives": [
{
"name": "Tuomas Hintikka"
@@ -27,28 +18,67 @@
"name_en": "Head of Excursions",
"representatives": [
{
"name": "Roope Palo"
"name": "Aino Tasapuro"
}
]
},
{
"name_fi": "Yrityssuhde- ja excursiovastaava",
"name_fi": "Yrityssuhdevastaava",
"name_en": "Apprentice of Corporate Relations",
"representatives": [
{
"name": "Axel Aurola"
},
{
"name": "Mikael Sundell"
},
{
"name": "Kaisa Lehtimäki"
"name": "Henrik Ervasti"
},
{
"name": "Timo Kaleva"
"name": "Samuel Södervall"
},
{
"name": "Markus Määttänen"
},
{
"name": "Aura Friman"
},
{
"name": "Anton Niemi"
},
{
"name": "Iida Toivanen"
},
{
"name": "Joona Kivioja"
},
{
"name": "Jussi Seppälä"
},
{
"name": "Roope Palo"
},
{
"name": "Väinö Saarinen"
},
{
"name": "Junias Vasama"
},
{
"name": "Anton Saari"
},
{
"name": "Väinö Silvenius"
}
]
},
{
"name_fi": "Excursiovastaava",
"name_en": "",
"representatives": [
{
"name": "Into Saarinen"
},
{
"name": "Otto Rinne"
}
]
}
+2 -3
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import rehypeRaw from "rehype-raw";
import rehypeSanitize from "rehype-sanitize";
@@ -81,10 +81,9 @@ const EventPageView: React.FC<EventPageViewProps> = ({ event }) => {
<Image
src={event.image || event.tags[0].icon}
alt={title}
objectFit="scale-down"
layout="responsive"
width={16}
height={9}
style={{ objectFit: "scale-down" }}
/>
</h1>
<div>
+2 -3
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import rehypeRaw from "rehype-raw";
import rehypeSanitize from "rehype-sanitize";
@@ -65,10 +65,9 @@ const FeedPageView: React.FC<FeedPageViewProps> = ({ post }) => {
<Image
src={post.image}
alt={title}
objectFit="scale-down"
layout="responsive"
width={16}
height={9}
style={{ objectFit: "scale-down" }}
/>
)}
</h1>
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import {
CTASection, TextSection, InfoBox, PageLink, Link,
@@ -61,10 +61,9 @@ const ForFreshmenPageView: React.FC = () => (
<Image
src="https://static.sahkoinsinoorikilta.fi/FTMK/IMG_6539.JPG"
alt="Kipparit"
layout="responsive"
width={100}
height={80}
objectFit="contain"
style={{ objectFit: "contain" }}
/>
</ImageContainer>
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import {
CTASection, TextSection, InfoBox, PageLink, Link,
@@ -78,10 +78,9 @@ const ForIntlPageView: React.FC = () => (
<Image
src="https://static.sahkoinsinoorikilta.fi/FTMK/Captains2025.jpg"
alt="Kipparit"
layout="responsive"
width={100}
height={80}
objectFit="contain"
style={{ objectFit: "contain" }}
/>
</ImageContainer>
+2 -3
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import {
CTASection, TextSection, InfoBox, PageLink, Link,
@@ -60,10 +60,9 @@ const FreshmenPageView: React.FC = () => (
<Image
src="https://static.sahkoinsinoorikilta.fi/FTMK/IMG_6539.JPG"
alt="Kipparit"
layout="responsive"
width={100}
height={80}
objectFit="contain"
style={{ objectFit: "contain" }}
/>
</ImageContainer>
+14 -14
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import styled from "styled-components";
import {
Divider,
@@ -93,43 +93,43 @@ const FrontPageView: React.FC<FrontPageViewProps> = ({ events, feed }) => (
<SponsorReel>
<div>
<Link to="https://new.abb.com/fi/">
<Image src={ABB} alt="ABB" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={ABB} alt="ABB" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://caruna.fi/">
<Image src={Caruna} alt="Caruna" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Caruna} alt="Caruna" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.nokia.com/">
<Image src={Nokia} alt="Nokia" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Nokia} alt="Nokia" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.ensto.com/fi/">
<Image src={Ensto} alt="Ensto" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Ensto} alt="Ensto" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.esett.com/">
<Image src={eSett} alt="eSett" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={eSett} alt="eSett" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.fingrid.fi/">
<Image src={Fingrid} alt="Fingrid" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Fingrid} alt="Fingrid" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.okmetic.com/fi/">
<Image src={Okmetic} alt="Okmetic" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Okmetic} alt="Okmetic" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.granlund.fi/">
<Image src={Granlund} alt="Granlund" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Granlund} alt="Granlund" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.eaton.com/fi/fi-fi.html">
<Image src={Eaton} alt="Eaton" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Eaton} alt="Eaton" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.ericsson.com/en">
<Image src={Ericsson} alt="Ericsson" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Ericsson} alt="Ericsson" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.saab.com/fi/markets/finland">
<Image src={Saab} alt="Saab" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Saab} alt="Saab" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.stul.fi/">
<Image src={STUL} alt="STUL" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={STUL} alt="STUL" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
<Link to="https://www.metso.com/fi/">
<Image src={Metso} alt="Metso" layout="responsive" width={200} height={100} objectFit="contain" />
<Image src={Metso} alt="Metso" width={200} height={100} style={{ objectFit: "contain" }} />
</Link>
</div>
<Link to="/yritysyhteistyo">Haluatko kuulla lisää yhteistyöstä kanssamme?</Link>
+2 -3
View File
@@ -1,5 +1,5 @@
import React from "react";
import Image from "next/legacy/image";
import Image from "next/image";
import {
CTASection, TextSection, PageLink, Link,
} from "@components/index";
@@ -81,8 +81,7 @@ const StudiesPageView: React.FC = () => (
alt="Ville Viikari"
width={300}
height={150}
layout="responsive"
objectFit="contain"
style={{ objectFit: "contain" }}
/>
<h6>Ville Viikari</h6>
<p>
+1 -1
View File
@@ -8,5 +8,5 @@
},
"skipJsErrors": true,
"appCommand": "npm run serve",
"appInitDelay": 2000
"appInitDelay": 10000
}
+1 -1
View File
@@ -1,6 +1,6 @@
import { Selector } from "testcafe";
import {
getSiteRoot, getPageUrl, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger
getSiteRoot, getPageUrl, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger,
} from "../utils";
const LOGGER = getPostRequestLogger("signupForm/");
+3 -3
View File
@@ -159,10 +159,10 @@ export const generateTestEvent = async (formIds = [], jwt_access: string) => (
export const sleep = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
export const waitForLogger = async (logger: RequestLogger) => {
for (let i = 0; i < 50; i++) {
for (let i = 0; i < 50; i += 1) {
await sleep(100);
if (logger.requests.length > 0 ) {
if (logger.requests.length > 0) {
return;
}
}
}
};
+1 -1
View File
@@ -5,7 +5,7 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"lib": [
"dom",
"esnext"