Compare commits
327 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a3ab778a84 | |||
| 4de56eef0b | |||
| b3eae06a5b | |||
| f8a711a869 | |||
| 19fbe71506 | |||
| 469f4f4da6 | |||
| cd2a58a76d | |||
| 84b2b450c6 | |||
| 7d3fd6857c | |||
| 9f44bf57f6 | |||
| 9d9211fa9c | |||
| c22bad5718 | |||
| 4fbec0b85c | |||
| 81be5a1e60 | |||
| 80ccf1bc66 | |||
| d75c6b4756 | |||
| 69c06636ab | |||
| 42ce058dc9 | |||
| 67627d4d16 | |||
| 4639397d25 | |||
| 630c0bce05 | |||
| b80942ee53 | |||
| a27c77e16c | |||
| 813479a602 | |||
| c12d4c1e73 | |||
| 453d20d345 | |||
| 7abb7dc414 | |||
| 103f2b163a | |||
| fda39d7372 | |||
| 3689dbc60c | |||
| 80a961d1f9 | |||
| db8c8ea2b9 | |||
| a854de921b | |||
| 9c8a2eb4ce | |||
| ff558534a0 | |||
| 56531b1cfc | |||
| a7c297354f | |||
| ff5da7a131 | |||
| 7412b652c1 | |||
| eb64777252 | |||
| 73869a4c15 | |||
| b6e0e5ea36 | |||
| 96a591b1c5 | |||
| 19ad40b969 | |||
| 482be66b43 | |||
| 5439ff9a56 | |||
| b7c06890fe | |||
| cdff86c0f3 | |||
| 984966f3af | |||
| fe015c3bce | |||
| a570fde9d7 | |||
| c683b2d61a | |||
| c23200401f | |||
| 827eab0531 | |||
| 1ee25d3447 | |||
| e62017691c | |||
| c116ea27cc | |||
| eb67fedde4 | |||
| 006a2dd548 | |||
| 49bb413424 | |||
| be4358b128 | |||
| db662959aa | |||
| 58b3e9594a | |||
| a120d7580d | |||
| 7b2393142f | |||
| 110ea83dc5 | |||
| d4bdeeb9ae | |||
| 2a44d99814 | |||
| 4e56f5d832 | |||
| 5ed2bfcbec | |||
| 9195bd2d59 | |||
| a50f6d2562 | |||
| ead8465673 | |||
| 749acccb07 | |||
| 5ef98ae1f5 | |||
| c449d2e1d0 | |||
| c8b846f518 | |||
| a80e92dcd4 | |||
| 95f02de0ae | |||
| b16ea3d5de | |||
| bad9ace8c8 | |||
| 1a2a870f18 | |||
| 34d8213156 | |||
| 238508f875 | |||
| 0fdc1aef3a | |||
| 71f209edde | |||
| 3181cede9b | |||
| 2579cd4763 | |||
| 63209bbf20 | |||
| 047c8656ac | |||
| e16a3bb8fc | |||
| 9b34d77c42 | |||
| a76ba2b1df | |||
| 5b59d36f76 | |||
| b381400903 | |||
| de93bb2a05 | |||
| 4a6b8093bc | |||
| d381e39f0f | |||
| acb335e010 | |||
| c630ebdb4d | |||
| 504b035b2a | |||
| 15843d8970 | |||
| d34e371d37 | |||
| e1e06f185e | |||
| a39e6fec4d | |||
| 12cce80502 | |||
| 1be5ef9cb4 | |||
| f7a65fabc0 | |||
| fbe20594dd | |||
| 734a91c490 | |||
| 7280edb99f | |||
| 613732aed2 | |||
| d22d6cb232 | |||
| 744aee88c4 | |||
| 1f2d33ce50 | |||
| 33ebf45627 | |||
| b0489b04ca | |||
| 217ffefb63 | |||
| 4df467988a | |||
| 0d272bc58c | |||
| 42fed752cc | |||
| e8e9fedf7c | |||
| 98e811e641 | |||
| dba12edb94 | |||
| 1360ed2f93 | |||
| 0a53ede99d | |||
| 82e5b40432 | |||
| 9040624ec4 | |||
| 5445d0b419 | |||
| 1434c434bf | |||
| e0e8fa6a78 | |||
| 5fa35bf681 | |||
| b9ed0181fc | |||
| def7c79d82 | |||
| fb8340e23e | |||
| 6e22c5496a | |||
| 62e2985f39 | |||
| 7323600314 | |||
| 2e4e862d87 | |||
| 63f0b5e99c | |||
| 58d9d6cc83 | |||
| 970cceef7f | |||
| 3c791f4b3b | |||
| cd52f3b609 | |||
| 6227a61eb6 | |||
| 570c1e0b48 | |||
| e6457d7487 | |||
| 247c8b793d | |||
| 282cff19a2 | |||
| 11fd154c4b | |||
| 54c23bd530 | |||
| 357ac71186 | |||
| bcd35e2041 | |||
| c116036748 | |||
| f0101059dd | |||
| eb467bf387 | |||
| cfce1ef859 | |||
| fcce680e80 | |||
| d649b4fc0c | |||
| 0373e07d45 | |||
| 9745276ffd | |||
| 42835f98f3 | |||
| 2b150c1d29 | |||
| 1beb35ee80 | |||
| 4f812dc0c8 | |||
| 955664a342 | |||
| 53f4f3de4c | |||
| b77ffff341 | |||
| c4e31e3c91 | |||
| 9f95b3d05f | |||
| fd7e41bffb | |||
| a062841b9c | |||
| 643ed1505a | |||
| 5dde3422e7 | |||
| 16504230b2 | |||
| 0fd26fa246 | |||
| a33dc3e77e | |||
| 2cf804be05 | |||
| 0fe6a29ffc | |||
| 8e1b0b9a30 | |||
| ba9d938092 | |||
| a2e55927ab | |||
| 1bda00ac9d | |||
| bfdfa28b5b | |||
| 96a3709f0c | |||
| a7fff40d74 | |||
| 5ac532176c | |||
| 325e51953a | |||
| 48d9437f59 | |||
| 3f2cb7717e | |||
| 2ea74f90ac | |||
| af2190c447 | |||
| f413435194 | |||
| e770722ad0 | |||
| 4cab856739 | |||
| 0e5f7339e8 | |||
| d53cd5f34c | |||
| 6c73fe9675 | |||
| a02e4891c2 | |||
| 57ef1484a9 | |||
| 25245939ff | |||
| 225626137a | |||
| fffd2588f9 | |||
| 95244d6e47 | |||
| 452f11eefe | |||
| 824ab05843 | |||
| bcbd61c18c | |||
| e4ab992be4 | |||
| 10ff54f6b0 | |||
| d5f6cb359f | |||
| d54652bcc7 | |||
| 24aa0839de | |||
| d62ce26759 | |||
| faf5269eba | |||
| 9a20cc009d | |||
| 057823c221 | |||
| 6891f87447 | |||
| 17633f3345 | |||
| 59e7194cf7 | |||
| 5a097080ee | |||
| f57bf98f31 | |||
| 433d9c67d7 | |||
| d538e6c92e | |||
| 1be914f37f | |||
| 437adf1fc2 | |||
| 521df27aa1 | |||
| 8bf38f512c | |||
| 3ffe8a1e17 | |||
| 32e541533f | |||
| 9f33c667d3 | |||
| 0e4e02e1b3 | |||
| cfc7dd11f5 | |||
| 63df5e6f5f | |||
| bdcf4840f5 | |||
| 0dc349161e | |||
| d101931020 | |||
| b4d41cd6a7 | |||
| ea82b493d5 | |||
| e767b395a9 | |||
| fe8f9328fa | |||
| 71d19d44cf | |||
| 4146af7207 | |||
| c243e76324 | |||
| 659d0e63a0 | |||
| 2c6c1d1e67 | |||
| eeb2f949c6 | |||
| 894e630664 | |||
| 56c13dbf64 | |||
| c3bbb3eda8 | |||
| 9c0e1a0e61 | |||
| 3b2d0596c9 | |||
| 2395321825 | |||
| 05b045c2fc | |||
| 8a6b2e0846 | |||
| faf12816bb | |||
| ea333b7c69 | |||
| e7ef69d75f | |||
| 03e6131fe8 | |||
| 87f803ca3e | |||
| 9c77cab47e | |||
| dd3eded4a1 | |||
| efacbe9c40 | |||
| c7a1502a26 | |||
| 59a4f3567e | |||
| 0ad59bfba6 | |||
| 6aa0b3fe19 | |||
| 88d5e57858 | |||
| 0301f3a996 | |||
| ee1be687bb | |||
| adb505d8ce | |||
| 07efb4caed | |||
| ce29f5a311 | |||
| e1d4a300c5 | |||
| 90f33048d7 | |||
| c55c7699c7 | |||
| 2e37072703 | |||
| aa90d97007 | |||
| 56669d5031 | |||
| 1e2ba706bf | |||
| c9b885df9e | |||
| 492d28381f | |||
| 22f306ff3c | |||
| c1ff6bbeae | |||
| bb3b9cb27f | |||
| 4449003cc8 | |||
| b4aa3c4871 | |||
| f91bb57932 | |||
| 045d48c988 | |||
| b4b29d6c9b | |||
| e5f6d5f659 | |||
| 6b05fcab4a | |||
| 3f660efa5a | |||
| dd3adae35f | |||
| e9fdeaeb5b | |||
| 77122aeea6 | |||
| c9d6c815d0 | |||
| be3ce96b4a | |||
| 1a8764f725 | |||
| 7547b10d70 | |||
| 0561c7ea50 | |||
| 084f7b7a81 | |||
| 01f663756b | |||
| 0979e84567 | |||
| 2b16776ee3 | |||
| fc4b327e4b | |||
| a525fe81c6 | |||
| 3c0e320bf3 | |||
| 648cec04ef | |||
| 65430c9017 | |||
| f70ff3eedf | |||
| 6596aa2ec8 | |||
| 6ce9c791b0 | |||
| d19613f08f | |||
| ff7143a5fa | |||
| 830538d56e | |||
| 2b1e9c6a0b | |||
| e997cdab8c | |||
| d98e44e17f | |||
| 067843d2b1 | |||
| c25e93ae2c | |||
| 8a05a4c459 | |||
| 48e4f2f6f8 | |||
| ae1c2b0d24 | |||
| e32070eb7b | |||
| f848259bbf | |||
| 6132aec379 | |||
| 0f344ad70d |
@@ -1,3 +1,4 @@
|
||||
NEXT_PUBLIC_DEPLOY_ENV=local
|
||||
NEXT_PUBLIC_API_URL=https://api.dev.sahkoinsinoorikilta.fi/api
|
||||
NEXT_PUBLIC_SITE_URL=https://dev.sahkoinsinoorikilta.fi
|
||||
NEXT_MQTT_HOST=mqtt.dev.sahkoinsinoorikilta.fi
|
||||
@@ -5,3 +5,4 @@ node_modules
|
||||
# don't lint nyc coverage output
|
||||
coverage
|
||||
next-env.d.ts
|
||||
tests
|
||||
|
||||
+28
-24
@@ -8,7 +8,7 @@ stages:
|
||||
- deploy
|
||||
|
||||
install:
|
||||
image: node:16
|
||||
image: node:20
|
||||
stage: setup
|
||||
script:
|
||||
- npm ci
|
||||
@@ -21,34 +21,35 @@ install:
|
||||
expire_in: 1 week
|
||||
|
||||
audit:
|
||||
image: node:16
|
||||
image: node:20
|
||||
needs: ["install"]
|
||||
allow_failure: true
|
||||
stage: audit
|
||||
script:
|
||||
- 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:
|
||||
@@ -66,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
|
||||
@@ -79,34 +89,32 @@ test:e2e:
|
||||
|
||||
publish:dev:
|
||||
stage: publish
|
||||
image: docker:stable
|
||||
image: docker:25-cli
|
||||
needs: ["build", "test:e2e", "es:lint", "css:lint"]
|
||||
services:
|
||||
- docker:stable-dind
|
||||
- docker:25-dind
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- docker info
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
- docker build . -t "$IMAGE_NAME":latest --build-arg SENTRY_AUTH_TOKEN="$SENTRY_AUTH_TOKEN" --build-arg NEXT_PUBLIC_DEPLOY_ENV=development --build-arg NEXT_PUBLIC_API_URL=https://api.dev.sahkoinsinoorikilta.fi/api --build-arg NEXT_PUBLIC_SITE_URL=https://dev.sahkoinsinoorikilta.fi
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
- docker push "$IMAGE_NAME":latest
|
||||
|
||||
publish:prod:
|
||||
stage: publish
|
||||
image: docker:stable
|
||||
image: docker:25-cli
|
||||
services:
|
||||
- docker:stable-dind
|
||||
- docker:25-dind
|
||||
only:
|
||||
- production
|
||||
script:
|
||||
- docker info
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
- docker build . -t "$IMAGE_NAME":prod --build-arg SENTRY_AUTH_TOKEN="$SENTRY_AUTH_TOKEN"
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
- docker push "$IMAGE_NAME":prod
|
||||
|
||||
deploy:dev:
|
||||
stage: deploy
|
||||
image: docker:stable
|
||||
image: docker:25-cli
|
||||
only:
|
||||
- master
|
||||
environment:
|
||||
@@ -120,15 +128,13 @@ deploy:dev:
|
||||
- echo "$DEV_TLSCACERT" > ~/.docker/ca.pem
|
||||
- echo "$DEV_TLSCERT" > ~/.docker/cert.pem
|
||||
- echo "$DEV_TLSKEY" > ~/.docker/key.pem
|
||||
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
script:
|
||||
- docker stack deploy --with-registry-auth -c stack-compose-dev.yml "$SERVICE_NAME"
|
||||
after_script:
|
||||
- docker logout "$CI_REGISTRY"
|
||||
|
||||
deploy:prod:
|
||||
stage: deploy
|
||||
image: docker:stable
|
||||
image: docker:25-cli
|
||||
only:
|
||||
- production
|
||||
environment:
|
||||
@@ -142,8 +148,6 @@ deploy:prod:
|
||||
- echo "$TLSCACERT" > ~/.docker/ca.pem
|
||||
- echo "$TLSCERT" > ~/.docker/cert.pem
|
||||
- echo "$TLSKEY" > ~/.docker/key.pem
|
||||
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
script:
|
||||
- docker stack deploy --with-registry-auth -c stack-compose.yml "$SERVICE_NAME"
|
||||
after_script:
|
||||
- docker logout "$CI_REGISTRY"
|
||||
|
||||
@@ -5,14 +5,25 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next
|
||||
* **[React](https://facebook.github.io/react/)** (17.x)
|
||||
* **[Typescript](https://www.typescriptlang.org/)** (4.x)
|
||||
* **[Next.js](https://nextjs.org/)** (12.x)
|
||||
* [Testcafe](https://devexpress.github.io/testcafe/) - E2E Testing framework
|
||||
* **[Testcafe](https://devexpress.github.io/testcafe/)** - E2E Testing framework
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone/download repo
|
||||
2. Install node v16 ([`nvm`](https://github.com/nvm-sh/nvm))
|
||||
3. `cp .env.local.example .env.local`
|
||||
4. `npm install`
|
||||
|
||||
Install node v16 with **[Node Version Manager](https://github.com/nvm-sh/nvm#installing-and-updating)**.
|
||||
|
||||
Set up your SSH key authentication in GitLab Profile Settings. Then clone the repository and checkout the master branch:
|
||||
```bash
|
||||
git clone git@gitlab.com:sahkoinsinoorikilta/vtmk/web2.0-frontend.git
|
||||
cd web2.0-frontend
|
||||
git checkout master
|
||||
```
|
||||
|
||||
Create local env file for development and install dependencies:
|
||||
```bash
|
||||
cp .env.local.example .env.local
|
||||
npm install
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
||||
Vendored
+2
-1
@@ -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
-19
@@ -1,27 +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({
|
||||
target: "server",
|
||||
/** @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",
|
||||
},
|
||||
],
|
||||
},
|
||||
}, 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));
|
||||
|
||||
Generated
+33194
-25204
File diff suppressed because it is too large
Load Diff
+101
-92
@@ -1,94 +1,103 @@
|
||||
{
|
||||
"name": "web2.0-frontend",
|
||||
"version": "0.1.0",
|
||||
"description": "Web 2.0 Frontend. React, Typescript.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-frontend.git"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"next.js",
|
||||
"typescript",
|
||||
"styled-components"
|
||||
],
|
||||
"author": "Aarni Halinen",
|
||||
"license": "MIT",
|
||||
"homepage": "https://sahkoinsinoorikilta.fi",
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"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:css": "stylelint \"./src/**/*.{ts,tsx}\"",
|
||||
"dev": "next dev",
|
||||
"start": "next dev",
|
||||
"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",
|
||||
"build-analyze": "ANALYZE=true npm run build",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/js-cookie": "^3.0.1",
|
||||
"@types/node": "^16.11.36",
|
||||
"@types/react": "^17.0.19",
|
||||
"@types/react-csv": "^1.1.2",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/shortid": "^0.0.29",
|
||||
"@types/styled-components": "^5.1.25",
|
||||
"@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-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-next": "^12.1.4",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"husky": "^7.0.4",
|
||||
"jest": "^27.5.1",
|
||||
"next-sitemap": "^2.5.19",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss-jsx": "^0.36.4",
|
||||
"postcss-syntax": "^0.36.2",
|
||||
"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"
|
||||
},
|
||||
"dependencies": {
|
||||
"@next/bundle-analyzer": "^12.1.4",
|
||||
"@rjsf/core": "^4.1.1",
|
||||
"@sentry/nextjs": "^6.19.6",
|
||||
"axios": "^0.26.1",
|
||||
"date-fns": "^2.28.0",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"js-cookie": "^3.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"next": "^12.1.4",
|
||||
"normalize.css": "^8.0.1",
|
||||
"react": "^17.0.2",
|
||||
"react-csv": "^2.2.2",
|
||||
"react-dnd": "15.0.2",
|
||||
"react-dnd-html5-backend": "15.0.2",
|
||||
"react-dnd-touch-backend": "15.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-is": "^17.0.2",
|
||||
"react-markdown": "^8.0.2",
|
||||
"react-mde": "^11.5.0",
|
||||
"react-toastify": "^8.2.0",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"rehype-sanitize": "^5.0.1",
|
||||
"sharp": "^0.30.3",
|
||||
"shortid": "^2.2.16",
|
||||
"styled-components": "^5.3.5",
|
||||
"swr": "^1.2.2"
|
||||
}
|
||||
"name": "web2.0-frontend",
|
||||
"version": "0.1.0",
|
||||
"description": "Web 2.0 Frontend. React, Typescript.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-frontend.git"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"next.js",
|
||||
"typescript",
|
||||
"styled-components"
|
||||
],
|
||||
"author": "Aarni Halinen",
|
||||
"license": "MIT",
|
||||
"homepage": "https://sahkoinsinoorikilta.fi",
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"postbuild": "next-sitemap",
|
||||
"export": "next export",
|
||||
"lint": "npm run lint:es && npm run lint:css",
|
||||
"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 --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": "^30.0.0",
|
||||
"@types/js-cookie": "^3.0.1",
|
||||
"@types/node": "^16.11.36",
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-csv": "^1.1.3",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/shortid": "^0.0.29",
|
||||
"@types/styled-components": "^5.1.25",
|
||||
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"babel-plugin-styled-components": "^2.0.7",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-next": "^13.5.11",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"husky": "^7.0.4",
|
||||
"jest": "^30.2.0",
|
||||
"next-sitemap": "^3.1.11",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss-jsx": "^0.36.4",
|
||||
"postcss-syntax": "^0.36.2",
|
||||
"stylelint": "^14.2.0",
|
||||
"stylelint-config-recommended": "^6.0.0",
|
||||
"stylelint-config-styled-components": "^0.1.1",
|
||||
"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": "^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": "^16.0.8",
|
||||
"normalize.css": "^8.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-csv": "^2.2.2",
|
||||
"react-dnd": "15.0.2",
|
||||
"react-dnd-html5-backend": "15.0.2",
|
||||
"react-dnd-touch-backend": "15.0.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-is": "^18.2.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-mde": "^11.5.0",
|
||||
"react-toastify": "^9.0.7",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"rehype-sanitize": "^5.0.1",
|
||||
"sharp": "^0.34.5",
|
||||
"shortid": "^2.2.16",
|
||||
"styled-components": "^5.3.5",
|
||||
"swr": "^1.2.2",
|
||||
"uuid": "^13.0.0"
|
||||
},
|
||||
"overrides": {
|
||||
"react-mde": {
|
||||
"react": "$react",
|
||||
"react-dom": "$react-dom"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
});
|
||||
@@ -11,7 +11,6 @@ export enum APIPath {
|
||||
FEED = "/feed/:id",
|
||||
JOBADS = "/jobads/:id",
|
||||
SIGNUPS = "/signup/:id",
|
||||
SIGNUPS_DELETE = "/signup/:id/delete",
|
||||
SIGNUPS_EDIT = "/signup/:id/edit",
|
||||
SIGNUP_FORMS = "/signupForm/:id",
|
||||
SIGNUP_FORMS_EMAIL = "/signupForm/:id/sendemail",
|
||||
|
||||
@@ -78,15 +78,6 @@ class SignupApi {
|
||||
}
|
||||
};
|
||||
|
||||
static userDeleteSignup = async (id: number, uuid: string): Promise<void> => {
|
||||
try {
|
||||
await deleteBackendAPI<{ message: "OK" }>({ path: APIPath.SIGNUPS_DELETE, urlParams: { id }, queryParams: { uuid } });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
static getForm = async (id: number, auth = false): Promise<SignupForm> => {
|
||||
try {
|
||||
return await getBackendAPI<SignupForm>({
|
||||
|
||||
@@ -49,6 +49,7 @@ const Panel = styled.div<{ $visible?: boolean }>`
|
||||
|
||||
interface AccordionProps {
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Accordion: React.FC<AccordionProps> = ({ title, children }) => {
|
||||
|
||||
@@ -3,9 +3,10 @@ import styled from "styled-components";
|
||||
import colors from "@theme/colors";
|
||||
|
||||
interface ButtonProps {
|
||||
onClick: (event?: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
onClick: () => void;
|
||||
buttonStyle: "hero" | "filled" | "filter" | "bordered";
|
||||
selected?: boolean;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const StyledButton = styled.button<{ $selected?: boolean }>`
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -18,8 +18,8 @@ const Row = styled.div`
|
||||
|
||||
const ImageContainer = styled.div`
|
||||
position: relative;
|
||||
height: 125px;
|
||||
width: 125px;
|
||||
height: 8rem;
|
||||
width: 8rem;
|
||||
flex-shrink: 0;
|
||||
|
||||
img {
|
||||
@@ -35,13 +35,19 @@ const Info = styled.div`
|
||||
margin-left: -20px;
|
||||
min-width: 150px;
|
||||
padding: 2rem;
|
||||
padding-top: 10px;
|
||||
color: ${colors.darkBlue};
|
||||
|
||||
& > p {
|
||||
font-size: 1.0rem;
|
||||
font-size: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& > a {
|
||||
font-weight: 400;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
& > h3 {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 500;
|
||||
@@ -67,8 +73,9 @@ const ContactCard: React.FC<ContactCardProps> = ({
|
||||
<Image
|
||||
src={image}
|
||||
alt={name}
|
||||
layout="fill"
|
||||
objectFit="scale-down"
|
||||
fill
|
||||
sizes="128px"
|
||||
style={{ objectFit: "cover" }}
|
||||
/>
|
||||
</ImageContainer>
|
||||
) : null}
|
||||
@@ -76,7 +83,7 @@ const ContactCard: React.FC<ContactCardProps> = ({
|
||||
<h3>{name}</h3>
|
||||
<p>{role_fi || role_en}</p>
|
||||
{phone ? <p>{phone}</p> : null}
|
||||
{email ? <p>{email}</p> : null}
|
||||
{email ? <a href={`mailto:${email}`}>{email}</a> : null}
|
||||
</Info>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import React from "react";
|
||||
import Image, { ImageProps } from "next/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]}
|
||||
/>
|
||||
|
||||
@@ -6,13 +6,14 @@ interface DropDownBoxProps {
|
||||
onMouseEnter: () => void;
|
||||
onMouseLeave: () => void;
|
||||
visible: boolean;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Box = styled.div`
|
||||
background-color: ${colors.white};
|
||||
border: 1px solid ${colors.black};
|
||||
margin-top: 0.8rem;
|
||||
position: absolute;
|
||||
/* margin-top: 0.8rem; hides cool onhover effect but fixes a gap problem */
|
||||
left: 0;
|
||||
top: 2.5rem;
|
||||
z-index: 20;
|
||||
|
||||
@@ -28,6 +28,9 @@ const Events: React.FC<EventsProps> = ({ events, lang }) => {
|
||||
const pageLinkText = t("Kaikki tapahtumat");
|
||||
const pageLinkDesc = `${t("löydät tapahtumakalenterista")}\xa0›`;
|
||||
|
||||
const googleCalendarText = t("Lisää killan");
|
||||
const googleCalendarDesc = `${t("Google-kalenteri")}\xa0›`;
|
||||
|
||||
const locale = isFi ? "fi-FI" : "en-GB";
|
||||
|
||||
const filteredEvents = events.map((e) => ({
|
||||
@@ -62,6 +65,9 @@ const Events: React.FC<EventsProps> = ({ events, lang }) => {
|
||||
<PageLink to="/kilta/toiminta#tapahtumat" desc={pageLinkDesc}>
|
||||
{pageLinkText}
|
||||
</PageLink>
|
||||
<PageLink to="https://calendar.google.com/calendar/u/0?cid=Y19mYjhhNWUwMjVjMjhkMTg5YTkzMWYyN2U5N2M4ODBmMGFhNTdmN2M1NDFlYzVhNjdlZDM4NzliYTVhNDEwNWI1QGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20" desc={googleCalendarDesc}>
|
||||
{googleCalendarText}
|
||||
</PageLink>
|
||||
</aside>
|
||||
|
||||
</CardSection>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Link } from "@components/index";
|
||||
import Icon, { IconType } from "@components/Icon";
|
||||
import colors from "@theme/colors";
|
||||
import breakpoints from "@theme/breakpoints";
|
||||
|
||||
@@ -28,6 +29,7 @@ const Content = styled.div`
|
||||
h4 {
|
||||
color: ${colors.lightBlue};
|
||||
padding: 1.5rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
@@ -67,6 +69,27 @@ const Map = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const SomeContainer = styled.div`
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: space-between;
|
||||
a {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
margin-right: 0.5rem;
|
||||
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
}
|
||||
svg{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
fill: ${colors.white};
|
||||
}
|
||||
`;
|
||||
|
||||
const FooterContent: React.FC = () => (
|
||||
<Content>
|
||||
<div>
|
||||
@@ -77,10 +100,8 @@ const FooterContent: React.FC = () => (
|
||||
<div>
|
||||
<p>TUAS-Talo</p>
|
||||
<p>Maarintie 8</p>
|
||||
<p>PL 15500, 00076 Aalto</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>Y-tunnus: 1627010-1</p>
|
||||
<p>hallitus@sahkoinsinoorikilta.fi</p>
|
||||
<Link to="/yhteystiedot">Yhteystiedot</Link>
|
||||
</div>
|
||||
@@ -92,6 +113,13 @@ const FooterContent: React.FC = () => (
|
||||
<Link to="https://sik.kuvat.fi">Kuvagalleria</Link>
|
||||
<Link to="https://static.sahkoinsinoorikilta.fi/logot-ja-grafiikka/">Logot ja grafiikka</Link>
|
||||
</div>
|
||||
<div>
|
||||
<SomeContainer>
|
||||
<Icon name={IconType.Facebook} link="https://www.facebook.com/AaltoYliopistonSIK/" />
|
||||
<Icon name={IconType.Instagram} link="https://www.instagram.com/sahkoinsinoorikilta/" />
|
||||
<Icon name={IconType.LinkedIn} link="https://www.linkedin.com/groups/8103057/" />
|
||||
</SomeContainer>
|
||||
</div>
|
||||
</Columns>
|
||||
</MarginSpace>
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,13 @@ const Sticky = styled.div<{ $isHidden?: boolean; $mobileMenuOpen?: boolean }>`
|
||||
transition: all 200ms ease-out;
|
||||
height: ${(p) => (p.$mobileMenuOpen ? "100vh" : "unset")};
|
||||
|
||||
/* tape to allow mobile dropdown menu scrolling */
|
||||
@media screen and (max-width: ${breakpoints.mobile}) {
|
||||
overflow-y: ${(p) => (p.$mobileMenuOpen ? "auto" : "visible")};
|
||||
overflow-x: hidden;
|
||||
-webkit-overflow-scrolling: touch; /* apparently some ios optimization for smoother scrolin' */
|
||||
}
|
||||
|
||||
${(p) => (p.$isHidden ? (`
|
||||
transition: all 200ms ease-in;
|
||||
transform: translateY(-100%);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -23,7 +23,11 @@ const Container = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const Hero: React.FC = ({ children }) => (
|
||||
type HeroProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
const Hero: React.FC<HeroProps> = ({ children }) => (
|
||||
<Container>
|
||||
{children}
|
||||
</Container>
|
||||
|
||||
@@ -35,6 +35,7 @@ type Colors = "darkBlue" | "lightTurquoise";
|
||||
|
||||
interface HeroAsideProps {
|
||||
bgColor: Colors;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
// TODO: Color combos
|
||||
|
||||
@@ -6,6 +6,7 @@ import breakpoints from "@theme/breakpoints";
|
||||
interface HeroPrimarySectionProps {
|
||||
header: string;
|
||||
text?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const Section = styled.section`
|
||||
|
||||
@@ -22,6 +22,7 @@ const Item = styled.div`
|
||||
|
||||
interface HeroSecondarySectionItemProps {
|
||||
note?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const HeroSecondarySectionItem: React.FC<HeroSecondarySectionItemProps> = ({ note, children }) => (
|
||||
@@ -52,6 +53,7 @@ const Items = styled.div`
|
||||
|
||||
interface HeroSecondarySectionProps {
|
||||
heading: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const HeroSecondarySection: React.FC<HeroSecondarySectionProps> = ({ heading, children }) => (
|
||||
|
||||
@@ -6,7 +6,11 @@ const Box = styled.div`
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const InfoBox: React.FC = ({ children }) => (
|
||||
type InfoBoxProps = {
|
||||
children?: React.ReactNode
|
||||
};
|
||||
|
||||
const InfoBox: React.FC<InfoBoxProps> = ({ children }) => (
|
||||
<Box>
|
||||
{children}
|
||||
</Box>
|
||||
|
||||
+18
-8
@@ -2,6 +2,7 @@ import React from "react";
|
||||
import NextJSLink, { LinkProps } from "next/link";
|
||||
|
||||
interface Props extends Omit<LinkProps, "href" | "as"> {
|
||||
children?: React.ReactNode;
|
||||
to: string;
|
||||
template?: string;
|
||||
target?: string;
|
||||
@@ -15,18 +16,27 @@ const Link: React.FC<Props> = ({
|
||||
}) => {
|
||||
if (template) {
|
||||
return (
|
||||
<NextJSLink href={template} passHref={passHref} as={to} {...props}>
|
||||
{/* eslint-disable-next-line jsx-a11y/anchor-has-content */}
|
||||
<a onClick={onClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} {...props} />
|
||||
</NextJSLink>
|
||||
<NextJSLink
|
||||
href={template}
|
||||
passHref={passHref}
|
||||
as={to}
|
||||
{...props}
|
||||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (to.startsWith("/") || to.startsWith("#")) {
|
||||
return (
|
||||
<NextJSLink href={to} passHref={passHref} {...props}>
|
||||
{/* eslint-disable-next-line jsx-a11y/anchor-has-content */}
|
||||
<a onClick={onClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} {...props} />
|
||||
</NextJSLink>
|
||||
<NextJSLink
|
||||
href={to}
|
||||
passHref={passHref}
|
||||
{...props}
|
||||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Link } from "@components/index";
|
||||
|
||||
interface NavbarChildLinkProps {
|
||||
to: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
|
||||
@@ -38,6 +38,7 @@ interface NavbarDropdownLinkProps {
|
||||
to: string;
|
||||
text: string;
|
||||
exploded?: boolean; // if exploded, show items directly underneath without a dropdown menu
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const NavbarDropdownLink: React.FC<NavbarDropdownLinkProps> = ({
|
||||
|
||||
@@ -10,20 +10,29 @@ export const renderNavigationItems = (mobile = false): JSX.Element => (
|
||||
<>
|
||||
<NavbarDropdownLink to="/kilta" text="Kilta ›" exploded={mobile}>
|
||||
<NavbarChildLink to="/kilta/toiminta">Toiminta</NavbarChildLink>
|
||||
<NavbarChildLink to="/kilta/fuksi">Fuksi</NavbarChildLink>
|
||||
<NavbarChildLink to="/kilta/jasenyys">Jäsenyys</NavbarChildLink>
|
||||
<NavbarChildLink to="/kilta/hallitus">Hallitus</NavbarChildLink>
|
||||
<NavbarChildLink to="/kilta/toimihenkilot">Toimihenkilöt</NavbarChildLink>
|
||||
<NavbarChildLink to="/kilta/vuokraa">Vuokraa kalustoa</NavbarChildLink>
|
||||
<NavbarChildLink to="/kilta/kunnianosoitukset">Kunnianosoitukset</NavbarChildLink>
|
||||
<NavbarChildLink to="https://static.sahkoinsinoorikilta.fi">Dokumenttiarkisto</NavbarChildLink>
|
||||
<NavbarChildLink to="https://sik.kuvat.fi">Kuvagalleria</NavbarChildLink>
|
||||
<NavbarChildLink to="/kilta/kilta-avustus">Kilta-avustus</NavbarChildLink>
|
||||
</NavbarDropdownLink>
|
||||
<NavbarDropdownLink to="/" text="New students ›" exploded={mobile}>
|
||||
<NavbarChildLink to="/newStudent/fuksi">Fukseille</NavbarChildLink>
|
||||
<NavbarChildLink to="/newStudent/fukseille_en">For Freshmen</NavbarChildLink>
|
||||
<NavbarChildLink to="/newStudent/forExchangers">For Exchange/MSc students</NavbarChildLink>
|
||||
</NavbarDropdownLink>
|
||||
<NavbarDropdownLink to="/opinnot_ja_ura" text="Opinnot ja ura" exploded={mobile} />
|
||||
<NavbarDropdownLink to="/yritysyhteistyo" text="Yritysyhteistyö" exploded={mobile} />
|
||||
<NavbarDropdownLink to="/yhteystiedot" text="Yhteystiedot" exploded={mobile}>
|
||||
{/* <NavbarChildLink to="https://en.wikipedia.org/wiki/Gay">Simo Höglund</NavbarChildLink> */}
|
||||
</NavbarDropdownLink>
|
||||
<NavbarDropdownLink to="/yhdenvertaisuus" text="Yhdenvertaisuus" exploded={mobile} />
|
||||
<NavbarDropdownLink to="/in_english" text="In English" exploded={mobile} />
|
||||
</>
|
||||
);
|
||||
|
||||
const Nav = styled.div`
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
@@ -47,6 +56,11 @@ const Nav = styled.div`
|
||||
@media screen and (max-width: ${breakpoints.mobile}) {
|
||||
justify-content: center;
|
||||
margin-left: 0;
|
||||
/* line 59 */
|
||||
border-top: 2px solid ${colors.lightBlue}; /* Add line above */
|
||||
padding-top: 0.5rem; /* Add some spacing */
|
||||
padding-bottom: 0.5rem; /* Add some spacing */
|
||||
cursor: pointer; /* Make entire nav clickable */
|
||||
}
|
||||
|
||||
svg {
|
||||
@@ -68,22 +82,12 @@ const DesktopContainer = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const SomeContainer = styled.div`
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
margin: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const MobileMenu = styled.div`
|
||||
display: flex;
|
||||
margin: 0 1rem;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
padding: 0 50%; /* Large clickable area horizontally cheeze */
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
@@ -93,9 +97,6 @@ const MobileMenu = styled.div`
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: ${breakpoints.mobile}) {
|
||||
margin-left: 3rem;
|
||||
}
|
||||
`;
|
||||
|
||||
interface NavigationProps {
|
||||
@@ -109,13 +110,8 @@ const Navigation: React.FC<NavigationProps> = ({ onMobileMenuOpen }) => {
|
||||
<DesktopContainer>
|
||||
{desktopItems}
|
||||
</DesktopContainer>
|
||||
<SomeContainer>
|
||||
<Icon name={IconType.Facebook} link="https://www.facebook.com/AaltoYliopistonSIK/" />
|
||||
<Icon name={IconType.Instagram} link="https://www.instagram.com/sahkoinsinoorikilta/" />
|
||||
<Icon name={IconType.LinkedIn} link="https://www.linkedin.com/groups/8103057/" />
|
||||
</SomeContainer>
|
||||
<MobileMenu>
|
||||
<Icon name={IconType.HamburgerMenu} onClick={onMobileMenuOpen} />
|
||||
<MobileMenu onClick={onMobileMenuOpen}>
|
||||
<Icon name={IconType.HamburgerMenu} />
|
||||
</MobileMenu>
|
||||
</Nav>
|
||||
);
|
||||
|
||||
@@ -4,8 +4,8 @@ import colors from "@theme/colors";
|
||||
import { renderNavigationItems } from "./Navigation";
|
||||
|
||||
const Nav = styled.nav`
|
||||
padding: 1rem 2rem;
|
||||
|
||||
padding: 1rem 1rem;
|
||||
padding-bottom: 20rem;
|
||||
a {
|
||||
fill: ${colors.lightBlue};
|
||||
color: ${colors.lightBlue};
|
||||
|
||||
@@ -6,6 +6,7 @@ import Link from "@components/Link";
|
||||
interface PageLinkProps {
|
||||
to: string;
|
||||
desc: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const StyledPageLink = styled.div`
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
const StyledSelect = styled.select`
|
||||
padding: 0.25rem;
|
||||
margin: 0.5rem;
|
||||
`;
|
||||
|
||||
const SelectWrapper = styled.div`
|
||||
padding: 0.5rem;
|
||||
`;
|
||||
|
||||
export { StyledSelect, SelectWrapper };
|
||||
+25
-13
@@ -1,5 +1,5 @@
|
||||
import React, {
|
||||
createContext, useContext, 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,
|
||||
};
|
||||
|
||||
@@ -67,9 +61,24 @@ const Reducer = (state: Store, action: Lang) => {
|
||||
};
|
||||
|
||||
const LocaleContext = createContext(initialState);
|
||||
|
||||
const LocaleStore: React.FC = ({ children }) => {
|
||||
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 {
|
||||
@@ -78,8 +87,11 @@ const LocaleStore: React.FC = ({ children }) => {
|
||||
// Just ignore if fails to store value in user's browser
|
||||
}
|
||||
};
|
||||
|
||||
const localeValue = useMemo(() => ({ ...state, changeLanguage }), [state]);
|
||||
|
||||
return (
|
||||
<LocaleContext.Provider value={{ ...state, changeLanguage }}>
|
||||
<LocaleContext.Provider value={localeValue}>
|
||||
{children}
|
||||
</LocaleContext.Provider>
|
||||
);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"ja hallitukset kuulumiset": "and what the board has been up to",
|
||||
"Kuvia tapahtumista": "Photos from events",
|
||||
"kuvagalleriassa": "in the photo gallery",
|
||||
"Lisää killan": "Add guild's",
|
||||
"Google-kalenteri": "Google-calendar",
|
||||
|
||||
"Hakemaasi sivua":
|
||||
"Page",
|
||||
@@ -48,7 +50,7 @@
|
||||
"Se aukeaa":
|
||||
"Signup opens at",
|
||||
|
||||
"Ilmoittauminen sulkeutuu":
|
||||
"Ilmoittautuminen sulkeutuu":
|
||||
"Signup closes at",
|
||||
|
||||
"Ilmoittauminen on umpeutunut!":
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -1,7 +1,8 @@
|
||||
import { OptionTypes } from "@components/Widgets/SignupQuestionsWidget/common";
|
||||
|
||||
export interface Signup {
|
||||
id?: number;
|
||||
id?: number; // Database id for completed signup
|
||||
submit_id?: string; // Signup request idempotency key
|
||||
signupForm_id: number;
|
||||
answer: string;
|
||||
}
|
||||
|
||||
+7
-12
@@ -1,12 +1,12 @@
|
||||
import React from "react";
|
||||
import Document, {
|
||||
Html, Head, Main, NextScript, DocumentContext, DocumentInitialProps,
|
||||
Html, Head, Main, NextScript, DocumentContext,
|
||||
} from "next/document";
|
||||
import { ServerStyleSheet } from "styled-components";
|
||||
import Favicons from "@components/Favicons";
|
||||
|
||||
export default class MyDocument extends Document<{ styleTags: unknown }> {
|
||||
static getInitialProps = async (ctx: DocumentContext): Promise<DocumentInitialProps> => {
|
||||
export default class MyDocument extends Document {
|
||||
static async getInitialProps(ctx: DocumentContext) {
|
||||
const sheet = new ServerStyleSheet();
|
||||
const originalRenderPage = ctx.renderPage;
|
||||
try {
|
||||
@@ -16,20 +16,15 @@ export default class MyDocument extends Document<{ styleTags: unknown }> {
|
||||
const initialProps = await Document.getInitialProps(ctx);
|
||||
return {
|
||||
...initialProps,
|
||||
styles: (
|
||||
<>
|
||||
{initialProps.styles}
|
||||
{sheet.getStyleElement()}
|
||||
</>
|
||||
),
|
||||
styles: [initialProps.styles, sheet.getStyleElement()],
|
||||
};
|
||||
} finally {
|
||||
sheet.seal();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
const { styleTags } = this.props;
|
||||
const { styles } = this.props;
|
||||
return (
|
||||
<Html lang="fi">
|
||||
<Head>
|
||||
@@ -37,7 +32,7 @@ export default class MyDocument extends Document<{ styleTags: unknown }> {
|
||||
<Favicons />
|
||||
</Head>
|
||||
<body>
|
||||
{styleTags}
|
||||
{styles}
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { NextPage } from "next";
|
||||
import useSWR from "swr";
|
||||
import { formatRelative } from "date-fns";
|
||||
import { formatRelative, formatISO } from "date-fns";
|
||||
import { toast } from "react-toastify";
|
||||
import styled from "styled-components";
|
||||
import AdminListCommon from "@views/admin/AdminListCommon";
|
||||
@@ -10,6 +10,7 @@ import AddLink from "@components/AddLink";
|
||||
import Event from "@models/Event";
|
||||
import EventApi from "@api/eventApi";
|
||||
import { fetcher, APIPath, API } from "@api/backend";
|
||||
import { StyledSelect, SelectWrapper } from "@components/Select";
|
||||
|
||||
const URL = "/admin/events";
|
||||
|
||||
@@ -37,42 +38,100 @@ const Renderer: React.FC = () => {
|
||||
const api: API = { path: APIPath.EVENTS, authenticated: true };
|
||||
const { data: events, error } = useSWR<Event[]>(api, fetcher);
|
||||
|
||||
const [sort, setSort] = useState<string>("start_time");
|
||||
const [order, setOrder] = useState<string>("descending");
|
||||
const [filter, setFilter] = useState<string>("all");
|
||||
|
||||
const eventSort = (a, b) => {
|
||||
let result = 0;
|
||||
if (order === "descending") {
|
||||
if (["start_time", "end_time"].includes(sort)) {
|
||||
result = new Date(b[sort]).getTime() - new Date(a[sort]).getTime();
|
||||
} else if (sort === "id") {
|
||||
result = b[sort] - a[sort];
|
||||
}
|
||||
} else if (order === "ascending") {
|
||||
if (["start_time", "end_time"].includes(sort)) {
|
||||
result = new Date(a[sort]).getTime() - new Date(b[sort]).getTime();
|
||||
} else if (sort === "id") {
|
||||
result = a[sort] - b[sort];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const dateFilter = (a) => {
|
||||
let result = true;
|
||||
|
||||
if (filter === "upcoming") {
|
||||
result = new Date(a.end_time).getTime() > Date.now();
|
||||
} else if (filter === "past") {
|
||||
result = new Date(a.end_time).getTime() < Date.now();
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
}, [sort, order, filter, events]);
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
return (
|
||||
<div>
|
||||
Failed loading events
|
||||
Failed loading events.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!events?.length) {
|
||||
return <div>No events.</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Start time</th>
|
||||
<th>End time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{events.map((event) => (
|
||||
<tr key={event.id}>
|
||||
<td><Link to={`${URL}/${event.id}`}>{event.title_fi}</Link></td>
|
||||
<td>{formatRelative(new Date(event.start_time), new Date())}</td>
|
||||
<td>{formatRelative(new Date(event.end_time), new Date())}</td>
|
||||
<td>
|
||||
<StyledButton $colorOverride="red" buttonStyle="filled" onClick={() => confirmDelete(event)}>
|
||||
Delete
|
||||
</StyledButton>
|
||||
</td>
|
||||
<div>
|
||||
<SelectWrapper>
|
||||
Sort by:
|
||||
<StyledSelect name="" onChange={(e) => setSort(e.target.value)}>
|
||||
<option value="start_time">Start time</option>
|
||||
<option value="end_time">End time</option>
|
||||
<option value="id">Creation order</option>
|
||||
</StyledSelect>
|
||||
Order:
|
||||
<StyledSelect name="" onChange={(e) => setOrder(e.target.value)}>
|
||||
<option value="descending">Descending</option>
|
||||
<option value="ascending">Ascending</option>
|
||||
</StyledSelect>
|
||||
Filter:
|
||||
<StyledSelect name="" onChange={(e) => setFilter(e.target.value)}>
|
||||
<option value="all">All</option>
|
||||
<option value="upcoming">Upcoming</option>
|
||||
<option value="past">Past</option>
|
||||
</StyledSelect>
|
||||
</SelectWrapper>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Start time</th>
|
||||
<th>End time</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{events.sort(eventSort).filter(dateFilter).map((event) => (
|
||||
<tr key={event.id}>
|
||||
<td><Link to={`${URL}/${event.id}`}>{event.title_fi}</Link></td>
|
||||
<td>{formatISO(new Date(event.start_time), { representation: "date" })}</td>
|
||||
<td>{formatISO(new Date(event.end_time), { representation: "date" })}</td>
|
||||
<td>
|
||||
<StyledButton $colorOverride="red" buttonStyle="filled" onClick={() => confirmDelete(event)}>
|
||||
Delete
|
||||
</StyledButton>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { NextPage } from "next";
|
||||
import useSWR from "swr";
|
||||
import { formatRelative } from "date-fns";
|
||||
import { formatRelative, formatISO } from "date-fns";
|
||||
import { toast } from "react-toastify";
|
||||
import styled from "styled-components";
|
||||
import AdminListCommon from "@views/admin/AdminListCommon";
|
||||
@@ -10,6 +10,7 @@ import AddLink from "@components/AddLink";
|
||||
import Post from "@models/Feed";
|
||||
import PostApi from "@api/feedApi";
|
||||
import { fetcher, APIPath, API } from "@api/backend";
|
||||
import { SelectWrapper, StyledSelect } from "@components/Select";
|
||||
|
||||
const URL = "/admin/feed";
|
||||
|
||||
@@ -37,6 +38,21 @@ const Renderer: React.FC = () => {
|
||||
const api: API = { path: APIPath.FEED, authenticated: true };
|
||||
const { data: feed, error } = useSWR<Post[]>(api, fetcher);
|
||||
|
||||
const [order, setOrder] = useState<string>("descending");
|
||||
|
||||
const feedSort = (a, b) => {
|
||||
let result = 0;
|
||||
if (order === "descending") {
|
||||
result = new Date(b.publish_time).getTime() - new Date(a.publish_time).getTime();
|
||||
} else if (order === "ascending") {
|
||||
result = new Date(a.publish_time).getTime() - new Date(b.publish_time).getTime();
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
}, [order, feed]);
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
return (
|
||||
@@ -52,29 +68,38 @@ const Renderer: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th>Publish time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{feed.map((post) => (
|
||||
<tr key={post.id}>
|
||||
<td><Link to={`${URL}/${post.id}`}>{post.title_fi}</Link></td>
|
||||
<td>{post.description_fi}</td>
|
||||
<td>{formatRelative(new Date(post.publish_time), new Date())}</td>
|
||||
<td>
|
||||
<StyledButton $colorOverride="red" buttonStyle="filled" onClick={() => confirmDelete(post)}>
|
||||
Delete
|
||||
</StyledButton>
|
||||
</td>
|
||||
<div>
|
||||
<SelectWrapper>
|
||||
Order:
|
||||
<StyledSelect name="" onChange={(e) => setOrder(e.target.value)}>
|
||||
<option value="descending">Descending</option>
|
||||
<option value="ascending">Ascending</option>
|
||||
</StyledSelect>
|
||||
</SelectWrapper>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Description</th>
|
||||
<th>Publish time</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{feed.sort(feedSort).map((post) => (
|
||||
<tr key={post.id}>
|
||||
<td><Link to={`${URL}/${post.id}`}>{post.title_fi}</Link></td>
|
||||
<td>{post.description_fi}</td>
|
||||
<td>{formatISO(new Date(post.publish_time), { representation: "date" })}</td>
|
||||
<td>
|
||||
<StyledButton $colorOverride="red" buttonStyle="filled" onClick={() => confirmDelete(post)}>
|
||||
Delete
|
||||
</StyledButton>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import useSWR from "swr";
|
||||
import { formatRelative } from "date-fns";
|
||||
import { formatRelative, formatISO } from "date-fns";
|
||||
import { toast } from "react-toastify";
|
||||
import styled from "styled-components";
|
||||
import AdminListCommon from "@views/admin/AdminListCommon";
|
||||
@@ -64,7 +64,7 @@ const Renderer: React.FC = () => {
|
||||
<td>{ad.description_fi}</td>
|
||||
<td>
|
||||
{ad.autohide_enabled
|
||||
? formatRelative(new Date(ad.autohide_at), new Date())
|
||||
? formatISO(new Date(ad.autohide_at), { representation: "date" })
|
||||
: "Disabled"}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { NextPage } from "next";
|
||||
import { formatRelative } from "date-fns";
|
||||
import useSWR from "swr";
|
||||
import { formatRelative, formatISO } from "date-fns";
|
||||
import { toast } from "react-toastify";
|
||||
import styled from "styled-components";
|
||||
import AdminListCommon from "@views/admin/AdminListCommon";
|
||||
@@ -8,6 +9,8 @@ import { Button, Link } from "@components/index";
|
||||
import AddLink from "@components/AddLink";
|
||||
import { SignupForm } from "@models/Signup";
|
||||
import SignupApi from "@api/signupApi";
|
||||
import { fetcher, APIPath, API } from "@api/backend";
|
||||
import { SelectWrapper, StyledSelect } from "@components/Select";
|
||||
|
||||
const URL = "/admin/signups";
|
||||
|
||||
@@ -31,57 +34,117 @@ const confirmDelete = async (signup: SignupForm) => {
|
||||
}
|
||||
};
|
||||
|
||||
const renderData = (signupForms: SignupForm[]) => {
|
||||
if (!signupForms || signupForms.length === 0) {
|
||||
const Renderer: React.FC = () => {
|
||||
const api: API = { path: APIPath.SIGNUP_FORMS, authenticated: true };
|
||||
const { data: signupForms, error } = useSWR<SignupForm[]>(api, fetcher);
|
||||
|
||||
const [sort, setSort] = useState<string>("start_time");
|
||||
const [order, setOrder] = useState<string>("descending");
|
||||
const [filter, setFilter] = useState<string>("all");
|
||||
|
||||
const signupFormSort = (a, b) => {
|
||||
let result = 0;
|
||||
if (order === "descending") {
|
||||
if (["start_time", "end_time"].includes(sort)) {
|
||||
result = new Date(b[sort]).getTime() - new Date(a[sort]).getTime();
|
||||
} else if (sort === "id") {
|
||||
result = b[sort] - a[sort];
|
||||
}
|
||||
} else if (order === "ascending") {
|
||||
if (["start_time", "end_time"].includes(sort)) {
|
||||
result = new Date(a[sort]).getTime() - new Date(b[sort]).getTime();
|
||||
} else if (sort === "id") {
|
||||
result = a[sort] - b[sort];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const dateFilter = (a) => {
|
||||
let result = true;
|
||||
|
||||
if (filter === "upcoming") {
|
||||
result = new Date(a.end_time).getTime() > Date.now();
|
||||
} else if (filter === "past") {
|
||||
result = new Date(a.end_time).getTime() < Date.now();
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
}, [sort, order, filter, signupForms]);
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
return (
|
||||
<div>
|
||||
Failed loading events.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!signupForms?.length) {
|
||||
return <div>No signup forms.</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Start time</th>
|
||||
<th>End time</th>
|
||||
<th>Sign-ups</th>
|
||||
<th>Send email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{signupForms.map((signupForm) => (
|
||||
<tr key={signupForm.id}>
|
||||
<td><Link to={`${URL}/${signupForm.id}`}>{signupForm.title_fi}</Link></td>
|
||||
<td>{formatRelative(new Date(signupForm.start_time), new Date())}</td>
|
||||
<td>{formatRelative(new Date(signupForm.end_time), new Date())}</td>
|
||||
<td><Link to={`${URL}/${signupForm.id}/list`}>View</Link></td>
|
||||
<td><Link to={`${URL}/${signupForm.id}/email`}>Send</Link></td>
|
||||
<td>
|
||||
<StyledButton $colorOverride="red" buttonStyle="filled" onClick={() => confirmDelete(signupForm)}>
|
||||
Delete
|
||||
</StyledButton>
|
||||
</td>
|
||||
<div>
|
||||
<SelectWrapper>
|
||||
Sort by:
|
||||
<StyledSelect name="" onChange={(e) => setSort(e.target.value)}>
|
||||
<option value="start_time">Start time</option>
|
||||
<option value="end_time">End time</option>
|
||||
<option value="id">Creation order</option>
|
||||
</StyledSelect>
|
||||
Order:
|
||||
<StyledSelect name="" onChange={(e) => setOrder(e.target.value)}>
|
||||
<option value="descending">Descending</option>
|
||||
<option value="ascending">Ascending</option>
|
||||
</StyledSelect>
|
||||
Filter:
|
||||
<StyledSelect name="" onChange={(e) => setFilter(e.target.value)}>
|
||||
<option value="all">All</option>
|
||||
<option value="upcoming">Upcoming</option>
|
||||
<option value="past">Past</option>
|
||||
</StyledSelect>
|
||||
</SelectWrapper>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Start time</th>
|
||||
<th>End time</th>
|
||||
<th>Sign-ups</th>
|
||||
<th>Send email</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{signupForms.sort(signupFormSort).filter(dateFilter).map((signupForm) => (
|
||||
<tr key={signupForm.id}>
|
||||
<td><Link to={`${URL}/${signupForm.id}`}>{signupForm.title_fi}</Link></td>
|
||||
<td>{formatISO(new Date(signupForm.start_time), { representation: "date" })}</td>
|
||||
<td>{formatISO(new Date(signupForm.end_time), { representation: "date" })}</td>
|
||||
<td><Link to={`${URL}/${signupForm.id}/list`}>View</Link></td>
|
||||
<td><Link to={`${URL}/${signupForm.id}/email`}>Send</Link></td>
|
||||
<td>
|
||||
<StyledButton $colorOverride="red" buttonStyle="filled" onClick={() => confirmDelete(signupForm)}>
|
||||
Delete
|
||||
</StyledButton>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const AdminSignupPage: NextPage = () => {
|
||||
const [forms, setForms] = useState<SignupForm[]>(null);
|
||||
|
||||
useEffect(() => {
|
||||
SignupApi.getForms(true)
|
||||
.then((res) => setForms(res));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AdminListCommon>
|
||||
<h1>Sign-up forms</h1>
|
||||
<AddLink text="Create signup form" to={`${URL}/create`} data-e2e="create-signup" />
|
||||
{renderData(forms)}
|
||||
</AdminListCommon>
|
||||
);
|
||||
};
|
||||
const AdminSignupPage: NextPage = () => (
|
||||
<AdminListCommon>
|
||||
<h1>Sign-up forms</h1>
|
||||
<AddLink text="Create signup form" to={`${URL}/create`} data-e2e="create-signup" />
|
||||
<Renderer />
|
||||
</AdminListCommon>
|
||||
);
|
||||
|
||||
export default AdminSignupPage;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import GuildroomPageView from "@views/GuildroomPage/GuildroomPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const GuildroomPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/kilta/guildroom`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<GuildroomPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default GuildroomPage;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import BoardPageView from "@views/BoardPage/BoardPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const BoardPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/kilta/hallitus`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<BoardPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default BoardPage;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import MembershipPageView from "@views/MembershipPage/MembershipPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const MembershipPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/kilta/jasenyys`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<MembershipPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default MembershipPage;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import FundPageView from "@views/FundPage/FundPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const FundPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/kilta/kilta-avustus`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<FundPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default FundPage;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import CommitteePageView from "@views/CommitteePage/CommitteePageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const CommitteePage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/yhteystiedot`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<CommitteePageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default CommitteePage;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import RentPageView from "@views/RentPage/RentPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const RentPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/kilta/vuokraa`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<RentPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default RentPage;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import ForInternationalPageView from "@views/ForInternationalPage/ForIntlPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const ForInternationalPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/newStudent/ForIntl`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<ForInternationalPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default ForInternationalPage;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import ContactsPageView from "@views/ForFreshmenPage/ForFreshmenPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const ContactsPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/newStudent/ForFreshmen`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<ContactsPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default ContactsPage;
|
||||
@@ -7,7 +7,7 @@ import PageWrapper from "@views/common/PageWrapper";
|
||||
const FreshmenPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/kilta/fuksi`} />
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/newStudent/fuksi`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<FreshmenPageView />
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { NextPage, GetStaticProps, GetStaticPaths } from "next";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
@@ -13,6 +13,7 @@ import PageWrapper from "@views/common/PageWrapper";
|
||||
import LoadingView from "@views/common/LoadingView";
|
||||
import noop from "@utils/noop";
|
||||
import NotFoundPage from "@pages/404";
|
||||
import { v4 as uuid } from "uuid";
|
||||
|
||||
type InitialProps = {
|
||||
initialForm: SignupForm;
|
||||
@@ -23,6 +24,7 @@ const FORM_URL = `${process.env.NEXT_PUBLIC_API_URL}/signupForm/`;
|
||||
const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
||||
const router = useRouter();
|
||||
const id = String(initialForm?.id ?? "");
|
||||
const SUBMIT_ID = uuid(); // Submission key, generated on page refresh
|
||||
const URL = `${FORM_URL}${id}/`;
|
||||
const { data: signupForm, error } = useSWR<SignupForm>(URL, (url) => axios.get(url).then((res) => res.data), { fallbackData: initialForm });
|
||||
|
||||
@@ -43,6 +45,7 @@ const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
||||
|
||||
const onSubmit = async ({ formData }: ISubmitEvent<string>) => {
|
||||
const payload: Signup = {
|
||||
submit_id: SUBMIT_ID, // This is for preventing duplicate requests; NOT RELATED TO THE SIGNUP ID IN DATABASE
|
||||
signupForm_id: signupForm.id,
|
||||
answer: formData,
|
||||
};
|
||||
|
||||
@@ -67,16 +67,6 @@ const EditSignUpPage: NextPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const onDelete = async () => {
|
||||
try {
|
||||
await SignupApi.userDeleteSignup(Number(signupId), uuid);
|
||||
toast.success("Sign-up deleted successfully 😎");
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error("Uh oh! Deleting sign-up failed! 😟");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PageWrapper>
|
||||
<SignUpPageView
|
||||
@@ -84,7 +74,6 @@ const EditSignUpPage: NextPage = () => {
|
||||
formData={formData}
|
||||
onChange={noop}
|
||||
onSubmit={onSubmit}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
</PageWrapper>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import ContactsPageView from "@views/EquityPage/EquityPageView";
|
||||
import PageWrapper from "@views/common/PageWrapper";
|
||||
|
||||
const ContactsPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/yhdenvertaisuus`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<ContactsPageView />
|
||||
</PageWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default ContactsPage;
|
||||
@@ -7,7 +7,7 @@ import PageWrapper from "@views/common/PageWrapper";
|
||||
const ContactsPage: NextPage = () => (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/yhteystiedot`} />
|
||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/kilta/yhteystiedot`} />
|
||||
</Head>
|
||||
<PageWrapper>
|
||||
<ContactsPageView />
|
||||
|
||||
@@ -31,7 +31,7 @@ const ActualPageHero: React.FC = () => (
|
||||
<HeroAsideItem
|
||||
header="Keksimistä ja rakentelua"
|
||||
link="#elepaja"
|
||||
linkText="Elektroniikkapaja ›"
|
||||
linkText="SIK-Paja ›"
|
||||
/>
|
||||
<HeroAsideItem
|
||||
header="Tiimipelejä ja liikuntaa"
|
||||
|
||||
@@ -111,13 +111,13 @@ const ActualPageView: React.FC<ActualPageViewProps> = ({ events, feed }) => (
|
||||
<div>
|
||||
<h6 id="elepaja">Rakenna kaikkea elektroniikkaan liittyvää</h6>
|
||||
<p>
|
||||
Elepaja on sähköinsinöörikillan ylläpitämä elektroniikkapaja, jossa opiskelijat pääsevät soveltamaan koulussa oppimiaan taitojaan käytännön projekteissa.
|
||||
SIK-PAJA on sähköinsinöörikillan ylläpitämä elektroniikkapaja, jossa opiskelijat pääsevät soveltamaan koulussa oppimiaan taitojaan käytännön projekteissa.
|
||||
Opiskelijat ovat aikojen saatossa rakentaneet pajalla mitä monimuotoisempia projekteja kuten ensimmäisiä ledivilkkujaan, teslakäämejä, robotteja ja radiolähettimiä.
|
||||
Jos elektroniikan rakentelu kiinnostaa tai tarvitset jonkun projektin kanssa apua niin tule ihmeessä käymään elepajalla.
|
||||
Pajan varustukseen kuluu perustyökalut, piirilevyn syövytysvälineet, kolvit, komponentit, pylväsporakone sekä laaja valikoima mittauslaitteita.
|
||||
Ota siis kola ja tule nauttimaan elepajan mukavasta ilmapiiristä Elepajan uusissa tiloissa kanditaattikeskuksessa ruokala alvarin alla.
|
||||
Pajan varustukseen kuluu perustyökalut, kolvit, komponentit sekä laaja valikoima mittauslaitteita.
|
||||
Tule tutustumaan toimintaamme Kandidaattikeskuksessa ruokala Alvarin alapuolella sijaitseviin tiloihimme.
|
||||
{" "}
|
||||
<Link to="https://elepaja.fi/tg">Tästä</Link> pääset liittymään elepajan Telegram-ryhmään.
|
||||
<Link to="https://t.me/sikpaja">Tästä</Link> pääset liittymään pajan Telegram-ryhmään.
|
||||
</p>
|
||||
<h6 id="urheilu">Urheilua ja lajikokeiluja</h6>
|
||||
<p>
|
||||
@@ -125,29 +125,30 @@ const ActualPageView: React.FC<ActualPageViewProps> = ({ events, feed }) => (
|
||||
Yksi näistä asioista on urheilun ja lajikokeiluiden tarjoaminen kiltalaisille.
|
||||
Järjestämme säännöllisesti muiden kiltojen kanssa yhteistyössä mahdollisuuksia pelata esimerkiksi säbää ja muita urheilulajeja.
|
||||
Jopa kesällä monien harrastuksien jäädessä tauolle, voit tulla messiin pelaamaan lentopalloa viikottain.
|
||||
Lajikokeiluita on tarjolla läpi vuoden ja niitä järjestetään yhteistyössä Otaniemen eri urheilu/harrastelujärjestöjen kanssa.
|
||||
Lajikokeiluita on tarjolla läpi vuoden ja niitä järjestetään yhteistyössä Otaniemen eri urheilu-/harrastelujärjestöjen kanssa.
|
||||
Pidä silmät auki killan nettisivujen tapahtumaosiossa ja liity <Link to="https://t.me/joinchat/DJRXxkKd0SMj0e9pBPXF1A">Telegram-ryhmään</Link>.
|
||||
Jos sinulla on ehdotuksia lajikokeiluihin, nykäise urheiluvastaavia tai hyvivointimestaria hihasta!
|
||||
Jos sinulla on ehdotuksia lajikokeiluihin, nykäise liikuntavastaavia tai hyvivointimestaria hihasta!
|
||||
</p>
|
||||
<h6 id="kulttuuri&juhla">Kulttuuria ja juhlia teatterista sitseihin</h6>
|
||||
<p>
|
||||
Hyvinvointitoimikunta järjestää urheilun ja lajikokeilun lisäksi myös kultturelleja tapahtumia ja menoja kiltalaisille.
|
||||
Hyvinvointitoimikunta järjestää urheilun ja lajikokeilujen lisäksi myös kultturelleja tapahtumia ja menoja kiltalaisille.
|
||||
Näihin kultturelleihin tapahtumiin kuuluu hauskaa laidasta laitaan, eli keittiöstä teatteriin ja teatterista mitä mielenkiintoimpiin museoihin.
|
||||
Lisäksi ohjelmatoimikunta viihdyttää kiltalaisia erilaisilla juhlilla rennoista saunailloista juhlavimpiin sitseihin.
|
||||
Lisäksi hupitoimikunta viihdyttää kiltalaisia erilaisilla juhlilla rennoista saunailloista juhlavimpiin sitseihin.
|
||||
Killan nettisivujen <Link to="#tapahtumat">Tapahtumat</Link>-osiosta voit tutkia tulevia kulttuuritapahtumia.
|
||||
</p>
|
||||
<h6 id="yritysyhteistyo">Yhteistyö yritysten kanssa</h6>
|
||||
<p>
|
||||
Killassa toimiva yritystoimikunta vastaa siitä, että killan talous pysyy pystyssä, mutta tämän lisäksi he myös tarjoavat kiltalaisille mahdollisuuksia solmia suhteita alamme huippuyritysten kanssa.
|
||||
Tällaisia mahdollisuuksia järjestetään excujen muodossa, joissa kiltalaiset usein pääsevät yrityksen omiin tiloihin tutustumaan yrityksen toimintaan ja henkilökuntaan, sekä erilaisten Otaniemessä järjestettävien yrityssuhdetapahtumien muodossa.
|
||||
Killassa toimiva yrityssuhdetoimikunta vastaa siitä, että killan talous pysyy pystyssä, mutta tämän lisäksi he myös tarjoavat kiltalaisille mahdollisuuksia solmia suhteita alamme huippuyritysten kanssa.
|
||||
Tällaisia mahdollisuuksia järjestetään excursioiden muodossa, joissa kiltalaiset usein pääsevät yrityksen omiin tiloihin tutustumaan yrityksen toimintaan ja henkilökuntaan,
|
||||
sekä erilaisten Otaniemessä järjestettävien yrityssuhdetapahtumien muodossa.
|
||||
Otaniemi-yritystapahtumia ovat esimerkiksi yrityksien kanssa yhteistyössä järjestetyt saunaillat, sekä jokavuotinen yritysbrunssi.
|
||||
Ilmottautumiset näihin tapahtumiin onnistuvat <Link to="#tapahtumat">Tapahtumat</Link>-osiosta killan nettisivuilta.
|
||||
</p>
|
||||
<h6 id="ulkosuhteet">Kansainvälisty ja luo suhteita</h6>
|
||||
<p>
|
||||
Ulkotoimikunta järjestää kiltalaisten iloksi tapahtumia monien ystävyysjärjestöjen kanssa niin suomessa kuin ulkomaillakin.
|
||||
UTMK:n järjestämissä tapahtumissa pääset kasvattamaan ystäväpiiriäsi Otaniemen ulkopuolelle ja jopa kansainvälistymään toden teolla.
|
||||
UTMK järjestää paljon toimintaa myös vaihto-opiskelijoille ja näihin tapahtumiin kannattaa ehdottomasti osallistua, jos tahtoo luoda ystävyyssuhteita ympäri maailman.
|
||||
Ulkosuhdevastaavat järjestävät kiltalaisten iloksi tapahtumia monien ystävyysjärjestöjen kanssa niin Suomessa kuin ulkomaillakin.
|
||||
Näissä tapahtumissa pääset kasvattamaan ystäväpiiriäsi Otaniemen ulkopuolelle ja jopa kansainvälistymään toden teolla.
|
||||
Kilta järjestää paljon toimintaa myös vaihto-opiskelijoille ja näihin tapahtumiin kannattaa ehdottomasti osallistua, jos tahtoo luoda ystävyyssuhteita ympäri maailman.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -159,9 +160,23 @@ const ActualPageView: React.FC<ActualPageViewProps> = ({ events, feed }) => (
|
||||
<p>Kuinka pääset kiltatoimintaan mukaan?</p>
|
||||
<div>
|
||||
<h6>Kiltakokous</h6>
|
||||
<p>Kiltakokous on killan ylintä toimivaltaa käyttävä elin, joka koostuu kaikista killan varsinaisista jäsenistä. Kiltakokouksen tehtävänä on valvoa hallituksen toimintaa ja päättää kaikkia kiltalaisia koskevista asioista. Kevään kiltakokouksessa hyväksytään toimintasuunnitelma ja talousarvio sekä annetaan vanhalle hallitukselle vastuunvapautus, mikäli tilinpäätös ja toimintakertomus hyväksytään. Syksyn kiltakokous on moniosainen, jonka 1. osassa valitaan hallituksen muodostaja. 2. osassa valitaan hallitus ja 3. osassa valitaan toimihenkilöt. Tämän kokouksen jälkeen killalla on kaikki toimijat valittuna seuraavalle vuodelle. Tämän lisäksi voidaan pitää ylimääräisiä kokouksia, jos hallitus, yleinen kokous tai vähintään 20 kiltalaista sitä kannattaa. Killan sääntöihin voit tutustua tarkemmin <Link to="https://static.sahkoinsinoorikilta.fi/saannot/killansaannot.pdf">täältä.</Link></p>
|
||||
<p>
|
||||
Kiltakokous on killan ylintä toimivaltaa käyttävä elin, joka koostuu kaikista killan varsinaisista jäsenistä.
|
||||
Kiltakokouksen tehtävänä on valvoa hallituksen toimintaa ja päättää kaikkia kiltalaisia koskevista asioista.
|
||||
Kevään kiltakokouksessa hyväksytään toimintasuunnitelma ja talousarvio sekä annetaan vanhalle hallitukselle vastuunvapautus, mikäli tilinpäätös ja toimintakertomus hyväksytään.
|
||||
Syksyn kiltakokous on moniosainen, jonka 1. osassa valitaan puheenjohtaja, 2. osassa valitaan hallitus ja 3. osassa valitaan toimihenkilöt.
|
||||
Tämän kokouksen jälkeen killalla on kaikki toimijat valittuna seuraavalle vuodelle.
|
||||
Tämän lisäksi voidaan pitää ylimääräisiä kokouksia, jos hallitus, yleinen kokous tai vähintään 20 kiltalaista sitä kannattaa.
|
||||
Killan sääntöihin voit tutustua tarkemmin <Link to="https://static.sahkoinsinoorikilta.fi/saannot/killansaannot.pdf">täältä.</Link>
|
||||
</p>
|
||||
<h6>Kähmyt</h6>
|
||||
<p>Killan kähmykaudella voit osoittaa kiinnostuksesi erilaisiin kiltarooleihin kähmyämällä kähmykoneen kautta. Kähmykausi käynnistyy alkusyksystä ja kestää syksyn 3. kiltakokoukseen asti, jossa kiltalaiset äänestävät ensivuoden toimihenkilöt. Hallitusvirkaan pyrkiessä täytyy kähmyäminen tehdä syksyn 2. kiltakokoukseen mennessä. Kähmyttäessäsi voit vapaasti valita tai keksiä roolin ja pyrkiä hallitukseen tai toimihenkilöksi. Muista kuitenkin, että kähmyäminen ei ole sitova killan tehtäviin vaan enemmänkin mielenkiinnon osoitus.</p>
|
||||
<p>
|
||||
Killan kähmykaudella voit osoittaa kiinnostuksesi erilaisiin kiltarooleihin kähmyämällä kähmykoneen kautta.
|
||||
Kähmykausi käynnistyy alkusyksystä ja kestää syksyn 3. kiltakokoukseen asti, jossa kiltalaiset äänestävät seuraavan vuoden toimihenkilöt.
|
||||
Hallitusvirkaan pyrkiessä täytyy kähmyäminen tehdä syksyn 2. kiltakokoukseen mennessä.
|
||||
Kähmyttäessäsi voit vapaasti valita tai keksiä roolin ja pyrkiä hallitukseen tai toimihenkilöksi.
|
||||
Muista kuitenkin, että kähmyäminen ei ole sitova killan tehtäviin vaan enemmänkin mielenkiinnon osoitus.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</TextSection>
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { TextSection, Link } from "@components/index";
|
||||
import colors from "@theme/colors";
|
||||
import ContactCard from "@components/ContactCard";
|
||||
|
||||
import BoardJson from "./board.json";
|
||||
|
||||
const orderedCommittees = [
|
||||
BoardJson,
|
||||
];
|
||||
|
||||
const blankProfile = "/img/blank_profile.png";
|
||||
|
||||
const BlueLink = styled(Link)`
|
||||
color: ${colors.blue1};
|
||||
|
||||
&:hover {
|
||||
color: ${colors.lightBlue};
|
||||
}
|
||||
`;
|
||||
|
||||
const Container = styled.div`
|
||||
color: ${colors.darkBlue};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50vw;
|
||||
|
||||
& > h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 4rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
|
||||
@media (max-width: 950px) {
|
||||
width: 100vw;
|
||||
}
|
||||
`;
|
||||
|
||||
const ContactContainer = styled.div`
|
||||
overflow-x: hidden;
|
||||
@media (max-width: 950px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const CommitteeContainer: React.FC<{
|
||||
committee: Committee;
|
||||
children: React.ReactNode;
|
||||
}> = ({ committee, children }) => (
|
||||
<Container>
|
||||
<div>
|
||||
{committee.roles.map((role) => (
|
||||
role.representatives.map((representative) => (
|
||||
<ContactCard
|
||||
key={representative.name}
|
||||
name={representative.name}
|
||||
phone={representative.phone_number}
|
||||
email={representative.email}
|
||||
image={representative.image || blankProfile}
|
||||
role_fi={role.name_fi}
|
||||
role_en={role.name_en}
|
||||
/>
|
||||
))
|
||||
))}
|
||||
</div>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
|
||||
interface Committee {
|
||||
name_fi: string;
|
||||
name_en: string;
|
||||
roles: Array<Role>;
|
||||
}
|
||||
|
||||
interface Role {
|
||||
name_fi: string;
|
||||
name_en: string;
|
||||
representatives: Array<Representative>
|
||||
}
|
||||
|
||||
interface Representative {
|
||||
name: string;
|
||||
phone_number?: string;
|
||||
email?: string;
|
||||
image?: string;
|
||||
}
|
||||
|
||||
const BoardPageView: React.FC = () => (
|
||||
<>
|
||||
<TextSection>
|
||||
<h1>Hallitus</h1>
|
||||
<div>
|
||||
<p>
|
||||
Tältä sivulta löydät killan hallituksen jäsenten yhteystiedot.
|
||||
</p>
|
||||
<p>
|
||||
{"Koko hallitukseen saa yhteyden lähettämällä sähköpostia osoitteeseen "}
|
||||
<BlueLink to="mailto:hallitus@sahkoinsinoorikilta.fi">
|
||||
hallitus@sahkoinsinoorikilta.fi
|
||||
</BlueLink>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
Muut yhteystiedot löydät <Link to="/yhteystiedot">täältä.</Link>
|
||||
</p>
|
||||
<p>
|
||||
{"Hallitukselle voi myös lähettää palautetta täyttämällä "}
|
||||
<BlueLink to="https://docs.google.com/forms/d/e/1FAIpQLSeD8Hm66uvwr7Xa2WGgOCfI2RS1NrZsmISf2QBKUcJf_stv8g/viewform?usp=sf_link">
|
||||
palautelomakkeen
|
||||
</BlueLink>
|
||||
. Lomakkeen vastauksia käydään läpi hallituksen kokouksissa.
|
||||
</p>
|
||||
</div>
|
||||
</TextSection>
|
||||
<ContactContainer>
|
||||
{orderedCommittees.map((json) => (
|
||||
<React.Fragment key={json.slug}>
|
||||
<TextSection id={json.slug}>
|
||||
<CommitteeContainer committee={json}>
|
||||
{(json.slug === "board")}
|
||||
</CommitteeContainer>
|
||||
</TextSection>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</ContactContainer>
|
||||
</>
|
||||
);
|
||||
|
||||
export default BoardPageView;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"slug": "board",
|
||||
"name_fi": "Hallitus",
|
||||
"name_fi": "Hallitus 2024",
|
||||
"name_en": "Board",
|
||||
"roles": [
|
||||
{
|
||||
@@ -8,22 +8,22 @@
|
||||
"name_en": "Chairman of the Board",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Mikko Suhonen",
|
||||
"name": "Emma Uusküla",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/mikko.jpg"
|
||||
"email": "emma.uuskula@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Emma.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Sihteeri",
|
||||
"name_en": "Secretary",
|
||||
"name_fi": "Varapuheenjohtaja",
|
||||
"name_en": "Vice Chair",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Emilia Kortelainen",
|
||||
"name": "Johannes Viirimäki",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/emilia.jpg"
|
||||
"email": "johannes.viirimaki@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Johannes.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -32,22 +32,22 @@
|
||||
"name_en": "Treasurer",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Esko Väänänen",
|
||||
"name": "Nelli Liljasto",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/esko.jpg"
|
||||
"email": "nelli.liljasto@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Nelli.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Fuksitoimikunnan Puheenjohtaja",
|
||||
"name_fi": "Fuksitoimikunnan puheenjohtaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Melisa Dönmez",
|
||||
"name": "Teemu Heikkinen",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/melisa.jpg"
|
||||
"email": "teemu.heikkinen@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Teemu.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -56,10 +56,10 @@
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Eveliina Ahonen",
|
||||
"name": "Henri Aito",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/eveliina.jpg"
|
||||
"email": "henri.aito@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Henri.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -68,10 +68,10 @@
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Sakke Kangas",
|
||||
"name": "Tuomas Rantamäki",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/sakke.jpg"
|
||||
"email": "tuomas.rantamaki@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/TuomasR.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -80,22 +80,10 @@
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Eero Ketonen",
|
||||
"name": "Matilda Ahonen",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/eero.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "ISOvastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Salla Lyytikäinen",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/salla.jpg"
|
||||
"email": "matilda.ahonen@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Matilda.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -104,10 +92,10 @@
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Sofia Öhman",
|
||||
"name": "Niklas Ritalahti",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/sofia.jpg"
|
||||
"email": "niklas.ritalahti@sahkoinsinoorikilta.fi",
|
||||
"image": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -116,10 +104,10 @@
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Iikka Huttu",
|
||||
"name": "Mikael Vatiainen",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/iikka.jpg"
|
||||
"email": "mikael.vatiainen@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Mikael.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -128,22 +116,22 @@
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Ilari Ojakorpi",
|
||||
"name": "Simeon Pursiainen",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/ilari.jpg"
|
||||
"email": "simeon.pursiainen@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Simeon.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Ulkomestari",
|
||||
"name_fi": "KV-fuksikapteeni",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Heidi Mäkitalo",
|
||||
"name": "Markus Aaltio",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/heidi.jpg"
|
||||
"email": "markus.aaltio@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Markus.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,10 +140,22 @@
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Tommi Oinonen",
|
||||
"name": "Tuomas Hintikka",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/tommmi.jpg"
|
||||
"email": "tuomas.hintikka@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/TuomasH.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Viestintämestari",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Yassine Ramid",
|
||||
"phone_number": null,
|
||||
"email": "yassine.ramid@sahkoinsinoorikilta.fi",
|
||||
"image": "https://static.sahkoinsinoorikilta.fi/img/board/Yassine.jpg"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Divider, TextSection, Link } from "@components/index";
|
||||
import colors from "@theme/colors";
|
||||
import ContactCard from "@components/ContactCard";
|
||||
|
||||
import FtmkJson from "./ftmk.json";
|
||||
import HtmkJson from "./htmk.json";
|
||||
import HvtmkJson from "./hvtmk.json";
|
||||
import MtmkJson from "./mtmk.json";
|
||||
import OptmkJson from "./optmk.json";
|
||||
import NtmkJson from "./ntmk.json";
|
||||
import PtmkJson from "./ptmk.json";
|
||||
import TtmkJson from "./ttmk.json";
|
||||
import YtmkJson from "./ytmk.json";
|
||||
import SwtmkJson from "./swtmk.json";
|
||||
import VtmkJson from "./vtmk.json";
|
||||
import LtmkJson from "./ltmk.json";
|
||||
import Others from "./others.json";
|
||||
|
||||
const orderedCommittees = [
|
||||
FtmkJson,
|
||||
HtmkJson,
|
||||
LtmkJson,
|
||||
HvtmkJson,
|
||||
MtmkJson,
|
||||
OptmkJson,
|
||||
YtmkJson,
|
||||
TtmkJson,
|
||||
PtmkJson,
|
||||
VtmkJson,
|
||||
SwtmkJson,
|
||||
NtmkJson,
|
||||
Others,
|
||||
];
|
||||
|
||||
const BlueLink = styled(Link)`
|
||||
color: ${colors.blue1};
|
||||
|
||||
&:hover {
|
||||
color: ${colors.lightBlue};
|
||||
}
|
||||
`;
|
||||
|
||||
const IndexUL = styled.ul`
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li::before {
|
||||
content: attr(data-icon);
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Index: React.FC<{ committees: typeof orderedCommittees }> = ({ committees }) => (
|
||||
<IndexUL>
|
||||
{committees.map(({ slug, name_fi }) => (
|
||||
<BlueLink to={`#${slug}`} key={slug}>
|
||||
<li data-icon="»">
|
||||
{name_fi}
|
||||
</li>
|
||||
</BlueLink>
|
||||
))}
|
||||
</IndexUL>
|
||||
);
|
||||
|
||||
const Container = styled.div`
|
||||
color: ${colors.darkBlue};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50vw;
|
||||
|
||||
& > h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 4rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
|
||||
@media (max-width: 950px) {
|
||||
width: 100vw;
|
||||
}
|
||||
`;
|
||||
|
||||
const ContactContainer = styled.div`
|
||||
overflow-x: hidden;
|
||||
@media (max-width: 950px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const TitleContainer = styled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 10px;
|
||||
flex-direction: column;
|
||||
margin: auto;
|
||||
`;
|
||||
|
||||
const CommitteeContainer: React.FC<{
|
||||
committee: Committee;
|
||||
children: React.ReactNode;
|
||||
}> = ({ committee, children }) => (
|
||||
<Container>
|
||||
<TitleContainer>
|
||||
<h2>
|
||||
{committee.name_fi || committee.name_en}
|
||||
</h2>
|
||||
</TitleContainer>
|
||||
<p>
|
||||
{committee.info}
|
||||
</p>
|
||||
<div>
|
||||
{committee.roles.map((role) => (
|
||||
role.representatives.map((representative) => (
|
||||
<ContactCard
|
||||
key={representative.name}
|
||||
name={representative.name}
|
||||
phone={representative.phone_number}
|
||||
email={representative.email}
|
||||
image={null}
|
||||
role_fi={role.name_fi}
|
||||
role_en={role.name_en}
|
||||
/>
|
||||
))
|
||||
))}
|
||||
</div>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
|
||||
interface Committee {
|
||||
name_fi: string;
|
||||
name_en: string;
|
||||
info: string;
|
||||
roles: Array<Role>;
|
||||
}
|
||||
|
||||
interface Role {
|
||||
name_fi: string;
|
||||
name_en: string;
|
||||
representatives: Array<Representative>
|
||||
}
|
||||
|
||||
interface Representative {
|
||||
name: string;
|
||||
phone_number?: string;
|
||||
email?: string;
|
||||
image?: string;
|
||||
}
|
||||
|
||||
const CommitteePageView: React.FC = () => (
|
||||
<>
|
||||
<TextSection>
|
||||
<h1>Toimihenkilöt</h1>
|
||||
<p>
|
||||
Tältä sivulta löytyvät killan toimihenkilöt sekä lyhyet kuvaukset toimikunnista.
|
||||
<br />
|
||||
<br />
|
||||
Toimihenkilöiden sähköpostiosoitteet ovat muotoa etunimi.sukunimi@sahkoinsinoorikilta.fi.
|
||||
</p>
|
||||
<aside>
|
||||
<div>
|
||||
<h6>Toimikuntaluettelo</h6>
|
||||
<Index committees={orderedCommittees} />
|
||||
</div>
|
||||
</aside>
|
||||
</TextSection>
|
||||
<ContactContainer>
|
||||
{orderedCommittees.map((json) => (
|
||||
<React.Fragment key={json.slug}>
|
||||
{(json.slug !== "board") && (
|
||||
<Divider />
|
||||
)}
|
||||
<TextSection id={json.slug}>
|
||||
<CommitteeContainer committee={json}>
|
||||
{(json.slug === "board") && (
|
||||
<div>
|
||||
<p>
|
||||
{"Koko hallitukseen saa yhteyden lähettämällä sähköpostia osoitteeseen "}
|
||||
<BlueLink to="mailto:hallitus@sahkoinsinoorikilta.fi">
|
||||
hallitus@sahkoinsinoorikilta.fi
|
||||
</BlueLink>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
{"Hallitukselle voi myös lähettää palautetta täyttämällä "}
|
||||
<BlueLink to="https://docs.google.com/forms/d/e/1FAIpQLSeD8Hm66uvwr7Xa2WGgOCfI2RS1NrZsmISf2QBKUcJf_stv8g/viewform?usp=sf_link">
|
||||
palautelomakkeen
|
||||
</BlueLink>
|
||||
. Lomakkeen vastauksia käydään läpi hallituksen kokouksissa.
|
||||
</p>
|
||||
<p>
|
||||
Toimihenkilöiden sähköpostiosoitteet ovat muotoa etunimi.sukunimi@sahkoinsinoorikilta.fi.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</CommitteeContainer>
|
||||
</TextSection>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</ContactContainer>
|
||||
</>
|
||||
);
|
||||
|
||||
export default CommitteePageView;
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"slug": "ftmk",
|
||||
"name_fi": "Fuksitoimikunta",
|
||||
"name_en": "",
|
||||
"info": "Fuksitoimikuntaan kuuluu fuksikapteenit, KV-kapteenit, ISOvastaava sekä KV-ISOvastaava. Fuksitoimikunta huolehtii fukseista ja fukseille annettavasta fuksikasvatuksesta. ISOvastaava ja KV-ISOvastaava ovat taas vastuussa killan ISOhenkilöistä ja heidän ohjaamisestaan.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Fuksitoimikunnan puheenjohtaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Teemu Heikkinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Fuksitoimikunnan puheenjohtajan adjutantti",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Henri Aito"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "KV-fuksikapteeni",
|
||||
"name_en": "International Fuksi Captain",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Markus Aaltio"
|
||||
},
|
||||
{
|
||||
"name": "Apollo Ailus"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "ISOvastaava",
|
||||
"name_en": "Tutor Coordinator",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Axel Aurola"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "KV-ISOvastaava",
|
||||
"name_en": "International Tutor Coordinator",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Igor Oinonen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"slug": "htmk",
|
||||
"name_fi": "Hupitoimikunta",
|
||||
"name_en": "Entertainment Committee",
|
||||
"info": "Hupitoimikunta järjestää päätoimenaan kaikenkirjavia tapahtumia, kuten sitsejä, saunailtoja sekä muita juhlia. Hupitoimikuntaa johtaa Hovimestari ja Hovineuvos. Toimikunnassa toimii Hovin lisäksi emäntiä ja isäntiä, jotka hoitavat juhlien käytännön järjestelyjä, esimerkiksi ruoanlaiton, kattauksen ja tarjoilun Hovin johdolla.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Hovimestari",
|
||||
"name_en": "Master of Ceremonies",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Tuomas Rantamäki"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Hovineuvos",
|
||||
"name_en": "Court Counsellor",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Matilda Ahonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Emäntä",
|
||||
"name_en": "Hostess",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Veera Lindroos"
|
||||
},
|
||||
{
|
||||
"name": "Aino Saarela"
|
||||
},
|
||||
{
|
||||
"name": "Nea Kanerva"
|
||||
},
|
||||
{
|
||||
"name": "Rosanna Reims"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Isäntä",
|
||||
"name_en": "Host",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Eemeli Hintsanen"
|
||||
},
|
||||
{
|
||||
"name": "André Palosaari"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"slug": "hvtmk",
|
||||
"name_fi": "Hyvinvointitoimikunta",
|
||||
"name_en": "Committee of Wellbeing",
|
||||
"info": "Hyvinvointitoimikunta järjestää monipuolisesti kiltalaisten hyvinvointia edistävää hyvän mielen toimintaa. Toimikunta koostuu liikunta-, retkeily-, kulttuuri- ja kiltahuonevastaavista, ja toimikuntaa johtaa hyvinvointimestari.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Hyvinvointimestari",
|
||||
"name_en": "Master of Wellbeing",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Niklas Ritalahti"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kulttuurivastaava",
|
||||
"name_en": "Culture Representative",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Peter Lindahl"
|
||||
},
|
||||
{
|
||||
"name": "Kuura Janhunen"
|
||||
},
|
||||
{
|
||||
"name": "Valentin Juhela"
|
||||
},
|
||||
{
|
||||
"name": "Leevi Leinonen"
|
||||
},
|
||||
{
|
||||
"name": "Milla Heino"
|
||||
},
|
||||
{
|
||||
"name": "Hocine Montenez"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Liikuntavastaava",
|
||||
"name_en": "Sports Representative",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Matias Hendolin"
|
||||
},
|
||||
{
|
||||
"name": "Sauli Hakala"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kiltahuonevastaava",
|
||||
"name_en": "Guild Room Representative",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Milja Kuusela"
|
||||
},
|
||||
{
|
||||
"name": "Aaro Rasilainen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Retkeilyvastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Tommi Sytelä"
|
||||
},
|
||||
{
|
||||
"name": "Konsta Hakala"
|
||||
},
|
||||
{
|
||||
"name": "Ville Lairila"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Yhdenvertaisuusvastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Saara Rossi"
|
||||
},
|
||||
{
|
||||
"name": "Aaron Löfgren"
|
||||
},
|
||||
{
|
||||
"name": "Milla Heino"
|
||||
},
|
||||
{
|
||||
"name": "Sauli Hakala"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"slug": "ltmk",
|
||||
"name_fi": "Lukkaritoimikunta",
|
||||
"name_en": "",
|
||||
"info": "Lukkaritoimikunta on vastuussa killan laulukulttuurin kehittämisestä sekä ylläpitämisestä. Toimikunnan muodostaa lukkarimestari, lukkarit sekä lukkarikisällit. Meidät tapaat sitseillä sekä muissa tapahtumissa muistuttamassa, että teekkari laulaa mieluummin kuin hyvin.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Lukkarimestari",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Leevi Oikarinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Lukkari",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aino Salmi"
|
||||
},
|
||||
{
|
||||
"name": "Ilmari Reponen"
|
||||
},
|
||||
{
|
||||
"name": "Jenni Marttinen"
|
||||
},
|
||||
{
|
||||
"name": "Peter Lindahl"
|
||||
},
|
||||
{
|
||||
"name": "Patrik Varteva"
|
||||
},
|
||||
{
|
||||
"name": "Tapio Immonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Lukkarikisälli",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Alex Hyytinen"
|
||||
},
|
||||
{
|
||||
"name": "Antti Salpakari"
|
||||
},
|
||||
{
|
||||
"name": "Iiris Kuulusa"
|
||||
},
|
||||
{
|
||||
"name": "Roman Shalamov"
|
||||
},
|
||||
{
|
||||
"name": "Samuel Södervall"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"slug": "mtmk",
|
||||
"name_fi": "Sössö-toimikunta",
|
||||
"name_en": "Media Committee",
|
||||
"info": "Sössö-toimikunta toimittaa Sössöä, Sähköinsinöörikillan ikiomaa lehteä, joka on ikänsä ja laatunsa puolesta Otaniemen eliittiä. Toimikunta julkaisee vuodessa kaksi painettua lehteä sekä lukuisia nettiartikkeleita ynnä muuta. Toimikunta hoitaa lisäksi myös valokuvat ja live-striimit.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Päätoimittaja",
|
||||
"name_en": "Editor in Chief",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Topi Manskinen",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Tyhjäntoimittaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Visa Kurvi",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Toimittaja",
|
||||
"name_en": "Journalist",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Joona Komonen"
|
||||
},
|
||||
{
|
||||
"name": "Olli Vaismaa"
|
||||
},
|
||||
{
|
||||
"name": "Jenni Marttinen"
|
||||
},
|
||||
{
|
||||
"name": "Ilmari Reponen"
|
||||
},
|
||||
{
|
||||
"name": "Igor Oinonen"
|
||||
},
|
||||
{
|
||||
"name": "Otto Kievimaa"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Toimittaja, Taittaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Atte Vitie"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Taittaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Otto Kievimaa"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Graafikko",
|
||||
"name_en": "Photographer & Graphic Artist",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Elian Salmimaa"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Valokuvaaja",
|
||||
"name_en": "Photographer",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Veikko Räty"
|
||||
},
|
||||
{
|
||||
"name": "Into Saarinen"
|
||||
},
|
||||
{
|
||||
"name": "Aaro Rasilainen"
|
||||
},
|
||||
{
|
||||
"name": "Anton Niemi"
|
||||
},
|
||||
{
|
||||
"name": "Veera Melvasalo"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"slug": "ntmk",
|
||||
"name_fi": "N-Toimikunta",
|
||||
"name_en": "",
|
||||
"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 nestori",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Karoliina Talvikangas"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "N-toimikunnan varanestori, Kiltapatruuna",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aaron Löfgren"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Sklubi-yhdyshenkilö",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Melisa Dönmez"
|
||||
},
|
||||
{
|
||||
"name": "Eveliina Ahonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kiltapatruuna",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"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": "Elian Salmimaa"
|
||||
},
|
||||
{
|
||||
"name": "Elias Damski"
|
||||
},
|
||||
{
|
||||
"name": "Elias Lindberg"
|
||||
},
|
||||
{
|
||||
"name": "Eero Ketonen"
|
||||
},
|
||||
{
|
||||
"name": "Verneri Turkki"
|
||||
},
|
||||
{
|
||||
"name": "Akseli Heikkinen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"slug": "optmk",
|
||||
"name_fi": "Opintotoimikunta",
|
||||
"name_en": "Study Committee",
|
||||
"info": "Opintotoimikunta vastaa edunvalvonnasta, killan tekemästä abimarkkinoinnista, sekä pitää yhteyttä korkeakoulun henkilökuntaan. Toimikunta järjestää opintoihin liittyviä tapahtumia, kuten opintosaunoja. Tomikunta koostuu opintomestarista ja opintovastaavista.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Opintomestari",
|
||||
"name_en": "Master of Studies",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Mikael Vatiainen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Opintovastaava",
|
||||
"name_en": "Study Coordinator",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Atu Vahla"
|
||||
},
|
||||
{
|
||||
"name": "Antti Lehtonen"
|
||||
},
|
||||
{
|
||||
"name": "Aleksi Liukkonen"
|
||||
},
|
||||
{
|
||||
"name": "Ilmari Reponen"
|
||||
},
|
||||
{
|
||||
"name": "Milla Heino"
|
||||
},
|
||||
{
|
||||
"name": "Samuel Södervall"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"slug": "others",
|
||||
"name_fi": "Muut",
|
||||
"name_en": "Other officials",
|
||||
"info": "",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Merikapteeni",
|
||||
"name_en": "Sea captain",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Ville Lairila",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Meripojankloppi",
|
||||
"name_en": "ship's boy",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Peter Lindahl",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"slug": "ptmk",
|
||||
"name_fi": "Pajatoimikunta",
|
||||
"name_en": "",
|
||||
"info": "Pajatoimikunta vastaa killan oman elektroniikkapajan eli SIK-pajan ylläpidosta ja kehityksestä. Toimikuntaa johtaa pajamestari ja toimikunta koostuu pajavastaavista ja pajakisälleistä.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Pajamestari",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Jere Oinonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Pajakisälli",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Otto Kievimaa"
|
||||
},
|
||||
{
|
||||
"name": "Đình Minh Trần"
|
||||
},
|
||||
{
|
||||
"name": "Valentin Juhela"
|
||||
},
|
||||
{
|
||||
"name": "Axel Söderberg"
|
||||
},
|
||||
{
|
||||
"name": "Auli Purolinna"
|
||||
},
|
||||
{
|
||||
"name": "Karl Lipping"
|
||||
},
|
||||
{
|
||||
"name": "Petrus Asikainen"
|
||||
},
|
||||
{
|
||||
"name": "Elmo Kankkunen"
|
||||
},
|
||||
{
|
||||
"name": "Samu Nyman"
|
||||
},
|
||||
{
|
||||
"name": "Hilkka Gröhn"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"slug": "swtmk",
|
||||
"name_fi": "SIKin Wapaa-aika -toimikunta",
|
||||
"name_en": "",
|
||||
"info": "Sikin Wapaa-aika -toimikunta eli tuttavallisemmin SiWa on killan uusin toimikunta. Toimikunnan tavoitteena on järjestää monipuolisesti erilaisia hassunhauskoja matalan kynnyksen tapahtumia kiltalaisille laidasta laitaan. Esimerkkejä SiWan tapahtumista ovat mm. wappulautta, pitsapäivä ja pokeriturnaus.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Myymäläpäällikkö",
|
||||
"name_en": "Head of sales",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Tiitus Koski"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Myyjä",
|
||||
"name_en": "Clerk",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Arvi Virkkunen"
|
||||
},
|
||||
{
|
||||
"name": "Valentin Juhela"
|
||||
},
|
||||
{
|
||||
"name": "Otto Rinne"
|
||||
},
|
||||
{
|
||||
"name": "Auli Purolinna"
|
||||
},
|
||||
{
|
||||
"name": "Patrik Varteva"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"slug": "ttmk",
|
||||
"name_fi": "Teknologiatoimikunta",
|
||||
"name_en": "Technology Committee",
|
||||
"info": "Teknologiatoimikunta huolehtii killan tekniikan toiminnasta. Toimikunnan vastuulle kuuluu killan tietojärjestelmien ylläpito ja kehitys sekä viestintäkanavien toimivuudesta huolehtiminen. Toimikunta koostuu teknologiamestarista ja teknologiavastaavista.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Teknologiamestari",
|
||||
"name_en": "Master of technology",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Simeon Pursiainen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Teknologiavastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Joona Maaranen"
|
||||
},
|
||||
{
|
||||
"name": "Aleksi Liukkonen"
|
||||
},
|
||||
{
|
||||
"name": "Elmo Kankkunen"
|
||||
},
|
||||
{
|
||||
"name": "Justus Ojala"
|
||||
},
|
||||
{
|
||||
"name": "Tommi Sytelä"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"slug": "vtmk",
|
||||
"name_fi": "Viestintätoimikunta",
|
||||
"name_en": "Communications Committee",
|
||||
"info": "Viestintätoimikunta huolehtii kiltalaisten tiedottamisesta, tuottaa sisältöä killan sosiaalisen median kanaviin ja suunnittelee killan myyntituotteita. Toimikuntaa johtaa killan viestintämestari ja toimikunta koostuu somevastaavista, brändivastaavista sekä videokuvaajista.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Viestintämestari",
|
||||
"name_en": "Head of communcations",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Yassine Ramid"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Somevastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aaron Löfgren"
|
||||
},
|
||||
{
|
||||
"name": "Elina Huttunen"
|
||||
},
|
||||
{
|
||||
"name": "Aura Friman"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Somevastaava, Brändivastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aapo Saranpää"
|
||||
},
|
||||
{
|
||||
"name": "Aino Svahn"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Brändivastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aleksandr Lemin"
|
||||
},
|
||||
{
|
||||
"name": "Roope Jaskari"
|
||||
},
|
||||
{
|
||||
"name": "Sauli Hakala"
|
||||
},
|
||||
{
|
||||
"name": "Ville Lairila"
|
||||
},
|
||||
{
|
||||
"name": "Aapo Nyyssönen"
|
||||
},
|
||||
{
|
||||
"name": "Mikko Sandström"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Videokuvaaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Veera Melvasalo"
|
||||
},
|
||||
{
|
||||
"name": "Aaro Rasilainen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"slug": "ytmk",
|
||||
"name_fi": "Yrityssuhdetoimikunta",
|
||||
"name_en": "Corporate Relations Committee",
|
||||
"info": "Yrityssuhdetoimikunta toimii linkkinä yritysmaailman ja Sähköinsinöörikillan välillä. Toimikunnan tehtäviin kuuluu esimerkiksi excursioiden eli yritysvierailujen järjestäminen, yrityssaunailtojen ja muiden yhteistyösopimuksilla rahoitettujen tapahtumien järjestäminen, sekä sponsoreiden hankinta Sähköinsinöörikillan puhtaanvalkoisiin haalareihin. Lisäksi yrityssuhdetoimikunnan vastuulla on ulkosuhteiden ylläpito ystävyysainejärjestöihin kotimaassa ja ulkomailla.",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Yrityssuhdemestari",
|
||||
"name_en": "Head of Corporate Relations",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Tuomas Hintikka"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Excursiomestari",
|
||||
"name_en": "Head of Excursions",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aino Tasapuro"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Yrityssuhdevastaava",
|
||||
"name_en": "Apprentice of Corporate Relations",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Mikael Sundell"
|
||||
},
|
||||
{
|
||||
"name": "Henrik Ervasti"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,211 +1,35 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Divider, TextSection, Link } from "@components/index";
|
||||
import colors from "@theme/colors";
|
||||
import ContactCard from "@components/ContactCard";
|
||||
|
||||
import BoardJson from "./board.json";
|
||||
import HvtmkJson from "./hvtmk.json";
|
||||
import MtmkJson from "./mtmk.json";
|
||||
import NtmkJson from "./ntmk.json";
|
||||
import OptmkJson from "./optmk.json";
|
||||
import OtmkJson from "./otmk.json";
|
||||
import EPtmkJson from "./eptmk.json";
|
||||
import SstmkJson from "./sstmk.json";
|
||||
import ShntmkJson from "./shntmk.json";
|
||||
import ShtmkJson from "./shtmk.json";
|
||||
import TtmkJson from "./ttmk.json";
|
||||
import UtmkJson from "./utmk.json";
|
||||
import YtmkJson from "./ytmk.json";
|
||||
import Others from "./others.json";
|
||||
|
||||
const orderedCommittees = [
|
||||
BoardJson,
|
||||
HvtmkJson,
|
||||
MtmkJson,
|
||||
NtmkJson,
|
||||
OptmkJson,
|
||||
OtmkJson,
|
||||
EPtmkJson,
|
||||
SstmkJson,
|
||||
ShntmkJson,
|
||||
ShtmkJson,
|
||||
TtmkJson,
|
||||
UtmkJson,
|
||||
YtmkJson,
|
||||
Others,
|
||||
];
|
||||
|
||||
const blankProfile = "/img/blank_profile.png";
|
||||
|
||||
const BlueLink = styled(Link)`
|
||||
color: ${colors.blue1};
|
||||
|
||||
&:hover {
|
||||
color: ${colors.lightBlue};
|
||||
}
|
||||
`;
|
||||
|
||||
const IndexUL = styled.ul`
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li::before {
|
||||
content: attr(data-icon);
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Index: React.FC<{ committees: typeof orderedCommittees }> = ({ committees }) => (
|
||||
<IndexUL>
|
||||
{committees.map(({ slug, name_fi }) => (
|
||||
<BlueLink to={`#${slug}`} key={slug}>
|
||||
<li data-icon="»">
|
||||
{name_fi}
|
||||
</li>
|
||||
</BlueLink>
|
||||
))}
|
||||
</IndexUL>
|
||||
);
|
||||
|
||||
const Container = styled.div`
|
||||
color: ${colors.darkBlue};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50vw;
|
||||
|
||||
& > h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 4rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
|
||||
@media (max-width: 950px) {
|
||||
width: 100vw;
|
||||
}
|
||||
`;
|
||||
|
||||
const ContactContainer = styled.div`
|
||||
margin-top: -13rem;
|
||||
overflow-x: hidden;
|
||||
@media (max-width: 950px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const TitleContainer = styled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 10px;
|
||||
flex-direction: column;
|
||||
margin: auto;
|
||||
`;
|
||||
|
||||
const CommitteeContainer: React.FC<{
|
||||
committee: Committee;
|
||||
}> = ({ committee, children }) => (
|
||||
<Container>
|
||||
<TitleContainer>
|
||||
<h2>
|
||||
{committee.name_fi || committee.name_en}
|
||||
</h2>
|
||||
</TitleContainer>
|
||||
<div>
|
||||
{committee.roles.map((role) => (
|
||||
role.representatives.map((representative) => (
|
||||
<ContactCard
|
||||
key={representative.name}
|
||||
name={representative.name}
|
||||
phone={representative.phone_number}
|
||||
email={representative.email}
|
||||
image={(committee.name_en === "Board") ? (representative.image || blankProfile) : null}
|
||||
role_fi={role.name_fi}
|
||||
role_en={role.name_en}
|
||||
/>
|
||||
))
|
||||
))}
|
||||
</div>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
|
||||
interface Committee {
|
||||
name_fi: string;
|
||||
name_en: string;
|
||||
roles: Array<Role>;
|
||||
}
|
||||
|
||||
interface Role {
|
||||
name_fi: string;
|
||||
name_en: string;
|
||||
representatives: Array<Representative>
|
||||
}
|
||||
|
||||
interface Representative {
|
||||
name: string;
|
||||
phone_number?: string;
|
||||
email?: string;
|
||||
image?: string;
|
||||
}
|
||||
import { TextSection, Link } from "@components/index";
|
||||
|
||||
const ContactsPageView: React.FC = () => (
|
||||
<>
|
||||
<TextSection>
|
||||
<h1>Yhteystiedot</h1>
|
||||
<TextSection>
|
||||
<h1>Yhteystiedot</h1>
|
||||
<div>
|
||||
<h6>Hallitus</h6>
|
||||
<p>
|
||||
Asiaa olisi, mutta kehen ottaa yhteyttä?
|
||||
<br />
|
||||
Tämä sivu yrittää valottaa sen oikean ihmisen puhelinnumeroa ja sähköpostiosoitetta.
|
||||
Koko hallitukseen saat yhteyden osoitteesta hallitus@sahkoinsinoorikilta.fi.
|
||||
Yksittäisten hallituksen jäsenten yhteystiedot löydät <Link to="/kilta/hallitus">täältä.</Link>
|
||||
</p>
|
||||
<aside>
|
||||
<div>
|
||||
<h6>Toimikuntaluettelo</h6>
|
||||
<Index committees={orderedCommittees} />
|
||||
</div>
|
||||
</aside>
|
||||
</TextSection>
|
||||
<ContactContainer>
|
||||
|
||||
{orderedCommittees.map((json) => (
|
||||
<React.Fragment key={json.slug}>
|
||||
{(json.slug !== "board") && (
|
||||
<Divider />
|
||||
)}
|
||||
<TextSection id={json.slug}>
|
||||
<CommitteeContainer committee={json}>
|
||||
{(json.slug === "board") && (
|
||||
<div>
|
||||
<p>
|
||||
{"Hallitukseen saa yhteyden lähettämällä sähköpostia "}
|
||||
<BlueLink to="mailto:hallitus@sahkoinsinoorikilta.fi">
|
||||
hallitus@sahkoinsinoorikilta.fi
|
||||
</BlueLink>
|
||||
{". Hallituksen yksittäisiin jäseniin saat yhteyden etunimi.sukunimi@sahkoinsinoorikilta.fi osoitteista."}
|
||||
</p>
|
||||
<p>
|
||||
{"Hallitukselle voi myös lähettää palautetta täyttämällä "}
|
||||
<BlueLink to="https://docs.google.com/forms/d/e/1FAIpQLSeD8Hm66uvwr7Xa2WGgOCfI2RS1NrZsmISf2QBKUcJf_stv8g/viewform?usp=sf_link">
|
||||
palautelomakkeen
|
||||
</BlueLink>
|
||||
{", lomakkeen vastauksia käydään läpi hallituksen kokouksissa."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
)}
|
||||
</CommitteeContainer>
|
||||
</TextSection>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</ContactContainer>
|
||||
</>
|
||||
<h6>Postiosoite</h6>
|
||||
<p>
|
||||
Aalto-yliopisto <br />
|
||||
Aalto-yliopiston Sähköinsinöörikilta ry <br />
|
||||
PL 15500 <br />
|
||||
00076 Aalto
|
||||
</p>
|
||||
<h6>Laskutus</h6>
|
||||
<p>
|
||||
Yhdistys : Aalto-yliopiston Sähköinsinöörikilta ry <br />
|
||||
Y-tunnus: 1627010-1 <br />
|
||||
Sähköpostilaskut: <a href="mailto:rahastonhoitaja@sahkoinsinoorikilta.fi">rahastonhoitaja@sahkoinsinoorikilta.fi</a>
|
||||
</p>
|
||||
<h6>Kiltahuone</h6>
|
||||
<p>
|
||||
Maarintie 8 <br />
|
||||
Huoneet 1130-1134
|
||||
</p>
|
||||
</div>
|
||||
</TextSection>
|
||||
);
|
||||
|
||||
|
||||
export default ContactsPageView;
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"slug": "eptmk",
|
||||
"name_fi": "Elepajatoimikunta",
|
||||
"name_en": "",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Pajapäävastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Oskari Ponkala"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Pajavastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Karl Lipping"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Pajakisälli",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Samu Nyman"
|
||||
},
|
||||
{
|
||||
"name": "Veikko Räty"
|
||||
},
|
||||
{
|
||||
"name": "Ville Lairila"
|
||||
},
|
||||
{
|
||||
"name": "Justus Ojala"
|
||||
},
|
||||
{
|
||||
"name": "Tommi Sytelä"
|
||||
},
|
||||
{
|
||||
"name": "Visa Kurvi"
|
||||
},
|
||||
{
|
||||
"name": "Petrus Asikainen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
{
|
||||
"slug": "hvtmk",
|
||||
"name_fi": "Hyvinvointitoimikunta",
|
||||
"name_en": "Committee of Wellbeing",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Hyvinvointimestari",
|
||||
"name_en": "Master of Wellbeing",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Sofia Öhman"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kulttuurivastaava",
|
||||
"name_en": "Culture Representative",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Juha Anttila"
|
||||
},
|
||||
{
|
||||
"name": "Aleksi Helin"
|
||||
},
|
||||
{
|
||||
"name": "Julia Pykälä-aho"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Liikuntavastaava",
|
||||
"name_en": "Sports Representative",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aaro Niskanen"
|
||||
},
|
||||
{
|
||||
"name": "Sauli Norja"
|
||||
},
|
||||
{
|
||||
"name": "Viola Palolahti"
|
||||
},
|
||||
{
|
||||
"name": "Eero Tihtonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kiltahuonevastaava",
|
||||
"name_en": "Guild Room Representative",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Patrick Linnanen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kiltapäiväkerhovastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Samu Nyman"
|
||||
},
|
||||
{
|
||||
"name": "Aleksanteri Vesala"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Retkeilyvastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Vilhelmiina Honkanen"
|
||||
},
|
||||
{
|
||||
"name": "Pinja Leppänen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
{
|
||||
"slug": "mtmk",
|
||||
"name_fi": "Sössö-toimikunta",
|
||||
"name_en": "Media Committee",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Puheenjohtaja, Päätoimittaja",
|
||||
"name_en": "Chair, Editor in Chief",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aino Suomi",
|
||||
"phone_number": null,
|
||||
"email": null,
|
||||
"image": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Toimittaja",
|
||||
"name_en": "Journalist",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Emmaleena Ahonen"
|
||||
},
|
||||
{
|
||||
"name": "Elias Hirvonen"
|
||||
},
|
||||
{
|
||||
"name": "Ville Lairila"
|
||||
},
|
||||
{
|
||||
"name": "Olli Komulainen"
|
||||
},
|
||||
{
|
||||
"name": "Pinja Salo"
|
||||
},
|
||||
{
|
||||
"name": "Tuukka Syrjänen"
|
||||
},
|
||||
{
|
||||
"name": "Aleksanteri Vesala"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Toimittaja & Valokuvaaja",
|
||||
"name_en": "Journalist & Photographer",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Jarno Mustonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Taittaja & Valokuvaaja",
|
||||
"name_en": "Layout Artist & Photographer",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Jonna Tammikivi"
|
||||
},
|
||||
{
|
||||
"name": "Sasu Saalasti"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Taittaja & Toimittaja",
|
||||
"name_en": "Layout Artist & Journalist",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Juuli Leppänen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Valokuvaaja",
|
||||
"name_en": "Photographer",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Toni Lyttinen"
|
||||
},
|
||||
{
|
||||
"name": "Sauli Norja"
|
||||
},
|
||||
{
|
||||
"name": "Rasmus Räsänen"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Valokuvaaja & Graafikko",
|
||||
"name_en": "Photographer & Graphic Artist",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Kalle Petäjäaho"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Graafikko",
|
||||
"name_en": "Photographer & Graphic Artist",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Otto Julkunen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Videokuvaaja",
|
||||
"name_en": "Videographer",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aaro Rasilainen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
{
|
||||
"slug": "ntmk",
|
||||
"name_fi": "N-Toimikunta",
|
||||
"name_en": "",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "N-toimikunnan puheenjohtaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Ville Kaakinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "N-toimikunnan varapuheenjohtaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Jami Hyytiäinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Sklubi-yhdyshenkilö",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Ville-Pekka Laakkonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Alumivastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Ella Eilola"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "N-Toimihenkilö",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Timi Tiira"
|
||||
},
|
||||
{
|
||||
"name": "Erna Virtanen"
|
||||
},
|
||||
{
|
||||
"name": "Emmaleena Ahonen"
|
||||
},
|
||||
{
|
||||
"name": "Jarno Mustonen"
|
||||
},
|
||||
{
|
||||
"name": "Pekka Aho"
|
||||
},
|
||||
{
|
||||
"name": "Mikko Haapamäki"
|
||||
},
|
||||
{
|
||||
"name": "Jonna Tammikivi"
|
||||
},
|
||||
{
|
||||
"name": "Juuli Leppänen"
|
||||
},
|
||||
{
|
||||
"name": "Simo Hakanummi"
|
||||
},
|
||||
{
|
||||
"name": "Tuomo Leino"
|
||||
},
|
||||
{
|
||||
"name": "Sasu Saalasti"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"slug": "optmk",
|
||||
"name_fi": "Opintotoimikunta",
|
||||
"name_en": "Study Committee",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Opintomestari",
|
||||
"name_en": "Master of Studies",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Iikka Huttu"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Opintovastaava",
|
||||
"name_en": "Study Coordinator",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Juulia Härkönen"
|
||||
},
|
||||
{
|
||||
"name": "Patrick Linnanen"
|
||||
},
|
||||
{
|
||||
"name": "Veeti Lahtinen"
|
||||
},
|
||||
{
|
||||
"name": "Pinja Leppänen"
|
||||
},
|
||||
{
|
||||
"name": "Mikko Sandström"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Abimarkkinointipäävastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Vilhelmiina Honkanen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Abimarkkinointivastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Liisa Haltia"
|
||||
},
|
||||
{
|
||||
"name": "Jenni Marttinen"
|
||||
},
|
||||
{
|
||||
"name": "Venla Vastamäki"
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"slug": "others",
|
||||
"name_fi": "Muut",
|
||||
"name_en": "Other officials",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Kiltapatruuna",
|
||||
"name_en": "Guild elder",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Toni Lyttinen",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
},
|
||||
{
|
||||
"name": "Emmaleena Ahonen",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
},
|
||||
{
|
||||
"name": "Johannes Ora",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
},
|
||||
{
|
||||
"name": "Antti Mäki",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "TEK-yhdyshenkilö",
|
||||
"name_en": "TEK contact person",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Oskari Ponkala",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Arkistonhoitaja",
|
||||
"name_en": "Archivist",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Timi Tiira",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Häirintäyhdydyshenkilö",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Toni Ojala",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
},
|
||||
{
|
||||
"name": "Aino Suomi",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
},
|
||||
{
|
||||
"name": "Sauli Norja",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Somevastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aaron Löfgren",
|
||||
"phone_number": null,
|
||||
"email": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
{
|
||||
"slug": "otmk",
|
||||
"name_fi": "Ohjelmatoimikunta",
|
||||
"name_en": "Entertainment Committee",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Hovimestari",
|
||||
"name_en": "Master of Ceremonies",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Sakke Kangas"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Hovineuvos",
|
||||
"name_en": "Court Counsellor",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Eero Ketonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Emäntä",
|
||||
"name_en": "Hostess",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Elina Huttunen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Isäntä",
|
||||
"name_en": "Host",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aleksi Saajakari"
|
||||
},
|
||||
{
|
||||
"name": "Aaron Löfgren"
|
||||
},
|
||||
{
|
||||
"name": "Verneri Turkki"
|
||||
},
|
||||
{
|
||||
"name": "Elias Lindberg"
|
||||
},
|
||||
{
|
||||
"name": "Roni Vallius"
|
||||
},
|
||||
{
|
||||
"name": "Elias Damski"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Lukkari",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Sakari Harjunpää"
|
||||
},
|
||||
{
|
||||
"name": "Eero Torpo"
|
||||
},
|
||||
{
|
||||
"name": "Niilo Ojala"
|
||||
},
|
||||
{
|
||||
"name": "Samuel Laine"
|
||||
},
|
||||
{
|
||||
"name": "Toni Ojala"
|
||||
},
|
||||
{
|
||||
"name": "Ville Kaakinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Lukkarikisällit",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Oona Karjalainen"
|
||||
},
|
||||
{
|
||||
"name": "Peter Lindahl"
|
||||
},
|
||||
{
|
||||
"name": "Aino Suomi"
|
||||
},
|
||||
{
|
||||
"name": "Sauli Norja"
|
||||
},
|
||||
{
|
||||
"name": "Venla Vastamäki"
|
||||
},
|
||||
{
|
||||
"name": "Kasper Skog"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"slug": "shntmk",
|
||||
"name_fi": "SIK100-historianäyttelytiimi",
|
||||
"name_en": "",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "SIK100-historianäyttelyvastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Timi Tiira"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Yrityssuhdevastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Ella Eilola"
|
||||
},
|
||||
{
|
||||
"name": "Taneli Myllykangas"
|
||||
},
|
||||
{
|
||||
"name": "Jesse Räisänen"
|
||||
},
|
||||
{
|
||||
"name": "Ville Kaakinen"
|
||||
},
|
||||
{
|
||||
"name": "Ville-Pekka Laakkonen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"slug": "shtmk",
|
||||
"name_fi": "SIK100-historiatoimikunta",
|
||||
"name_en": "",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "SIK100-historiatoimikunnan puheenjohtaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Joni Kurvinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "SIK100-historiatoimihenkilö",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Anni Parkkila"
|
||||
},
|
||||
{
|
||||
"name": "Erna Virtanen"
|
||||
},
|
||||
{
|
||||
"name": "Tommi Askola"
|
||||
},
|
||||
{
|
||||
"name": "Mikko Leino"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"slug": "sstmk",
|
||||
"name_fi": "SIK100-toimikunta",
|
||||
"name_en": "",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Puheenjohtaja",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Erna Virtanen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Webivastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Jaakko Koskela"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Markkinointivastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Sasu Saalasti"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Yritysvastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Juuli Leppänen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Seminaarivastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Sini Huhtinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kevätkarnevaalimajuri",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Olli Komulainen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "PoTa100-pääjuhlatirehtööri",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Emmaleena Ahonen"
|
||||
},
|
||||
{
|
||||
"name": "Jonna Tammikivi"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "PoTa100-jatkotirehtööri",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Mikael Liimatainen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "PoTa100-sillistirehtööri",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Tuomo Leino"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"slug": "ttmk",
|
||||
"name_fi": "Teknologiatoimikunta",
|
||||
"name_en": "",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Teknologiamestari",
|
||||
"name_en": "Master of technology",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Ilari Ojakorpi"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Teknologianeuvos",
|
||||
"name_en": "Technology Advisor",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aarni Halinen"
|
||||
},
|
||||
{
|
||||
"name": "Jaakko Koskela"
|
||||
},
|
||||
{
|
||||
"name": "Toni Lyttinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Teknologiakisälli",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Elmo Kankkunen"
|
||||
},
|
||||
{
|
||||
"name": "Antti Eronen"
|
||||
},
|
||||
{
|
||||
"name": "Justus Ojala"
|
||||
},
|
||||
{
|
||||
"name": "Lasse Ruokokoski"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
{
|
||||
"slug": "utmk",
|
||||
"name_fi": "Ulkotoimikunta",
|
||||
"name_en": "External Affairs Committeee",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Ulkomestari",
|
||||
"name_en": "Master of External Affairs",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Heidi Mäkitalo"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kv-Fuksikapteeni",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Suvi Karanta"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Kv-ISOvastaava",
|
||||
"name_en": "International Tutor Coordinator",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Pyry Vaara"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "International Helper",
|
||||
"name_en": "International Helper",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Aaro Niskanen"
|
||||
},
|
||||
{
|
||||
"name": "Eerik Eskola"
|
||||
}
|
||||
,
|
||||
{
|
||||
"name": "Oona Karjalainen"
|
||||
},
|
||||
{
|
||||
"name": "Aleksi Helin"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Ulkosuhdevastaava",
|
||||
"name_en": "Apprentice of External Affairs",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Nestori Yrjönkoski"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Ora"
|
||||
},
|
||||
{
|
||||
"name": "Eino Tyrvänen"
|
||||
},
|
||||
{
|
||||
"name": "Jenni Marttinen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Ulkowanhus & Ulkopatruuna",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Oliver Hiekkamies"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "KVummisetä",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Elias Hirvonen"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"slug": "ytmk",
|
||||
"name_fi": "Yrityssuhdetoimikunta",
|
||||
"name_en": "Corporate Relations Committee",
|
||||
"roles": [
|
||||
{
|
||||
"name_fi": "Yrityssuhdemestari",
|
||||
"name_en": "Master of Corporate Relations",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Tommi Oinonen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Excursiopäävastaava",
|
||||
"name_en": "Head of Excursions",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Henry Gustafsson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Excursiovastaava",
|
||||
"name_en": "",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Visa Kurvi"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name_fi": "Yrityssuhdevastaava",
|
||||
"name_en": "Apprentice of Corporate Relations",
|
||||
"representatives": [
|
||||
{
|
||||
"name": "Melina Sundell"
|
||||
},
|
||||
{
|
||||
"name": "Emma Reinikainen"
|
||||
},
|
||||
{
|
||||
"name": "Iida Luoma"
|
||||
},
|
||||
{
|
||||
"name": "Elma Tuohimetsä"
|
||||
},
|
||||
{
|
||||
"name": "Nestori Yrjönkoski"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -25,7 +25,7 @@ const CorporatePageHero: React.FC = () => (
|
||||
<HeroAsideItem
|
||||
header="LinkedIn"
|
||||
link="https://linkedin.com/groups/8103057"
|
||||
linkText="Killan LinkedIn ryhmä"
|
||||
linkText="Killan LinkedIn-ryhmä"
|
||||
/>
|
||||
</HeroAside>
|
||||
</Hero>
|
||||
|
||||
@@ -6,8 +6,10 @@ import JobAd from "@models/JobAd";
|
||||
import CorporatePageHero from "./CorporatePageHero";
|
||||
import JobAdList from "./JobAdList";
|
||||
|
||||
import BoardJson from "../BoardPage/board.json";
|
||||
|
||||
const EXCURSION_RULES = "https://static.sahkoinsinoorikilta.fi/saannot/excursiosaannot.pdf";
|
||||
const CORPORATE_MASTER_MAIL = "tommi.oinonen@sahkoinsinoorikilta.fi";
|
||||
const CORPORATE_MASTER_INFO = BoardJson.roles.filter((role) => role.name_fi === "Yrityssuhdemestari")[0].representatives[0];
|
||||
|
||||
interface CorporatePageViewProps {
|
||||
jobAds: JobAd[];
|
||||
@@ -63,18 +65,16 @@ const CorporatePageView: React.FC<CorporatePageViewProps> = ({ jobAds }) => (
|
||||
|
||||
<h6>Potentiaalin Tasaus</h6>
|
||||
<p>
|
||||
Kiltamme viettää perinteikkäitä vuosijuhliaan helmikuun kolmantena lauantaina.
|
||||
Kiltamme viettää perinteikästä vuosijuhlaansa helmikuun kolmantena lauantaina.
|
||||
Potentiaalin Tasaus on kiltamme juhlavin ja rakkain tapahtuma.
|
||||
Yrityksillä on mahdollisuus osallistua vuosijuhliin niin pienellä kuin suurellakin panoksella.
|
||||
Killan 100-vuotisjuhla PoTa100 lähestyy myös kovaa vauhtia.
|
||||
Jos yrityksesi on kiinnostunut 100-vuotisjuhlasta, kannattaa ohjautua osoitteeseen <Link to="https://sik100.fi">sik100.fi</Link>.
|
||||
Yrityksillä on mahdollisuus osallistua vuosijuhliin niin pienellä kuin suurellakin panoksella!
|
||||
</p>
|
||||
|
||||
<h6>Killan nettisivut ja työpaikkamainokset</h6>
|
||||
<p>
|
||||
Killan nettisivuilla on listattu killan yritysyhteistyökumppanit.
|
||||
Killan sivuilta löytyvät myös yritysyhteistyökumppaneiden avoimet työpaikkamainokset.
|
||||
Nämä mainokset ohjataan killan jäsenistölle eteenpäin myös viikottaisin kiltamailin kautta, jotta kaikki mainokset saavat parhaan mahdollisen näkyvyyden kiltalaisten arjessa.
|
||||
Nämä mainokset ohjataan killan jäsenistölle eteenpäin myös viikoittaisen kiltamailin kautta, jotta kaikki mainokset saavat parhaan mahdollisen näkyvyyden kiltalaisten arjessa.
|
||||
</p>
|
||||
|
||||
<h6>Sössö</h6>
|
||||
@@ -82,7 +82,7 @@ const CorporatePageView: React.FC<CorporatePageViewProps> = ({ jobAds }) => (
|
||||
<Link to="https://sosso.fi">Sössö</Link> on Sähköinsinöörikillan hauska ja rakas opiskelijalehti.
|
||||
Sössö on kerännyt suosiota ja kartuttanut lukijamäärää jo vuodesta 1969 asti.
|
||||
Sössö ilmestyy perinteisesti paperisena, mutta myös Netti-Sössössä julkaistaan jatkuvasti uusia artikkeleja.
|
||||
Sössö tavoittaa noin tuhat elektroniikan, sähkötekniikan ja tietoliikennetekniikan opiskelijaa sekä koko tiedekunnan henkilökunnan.
|
||||
Sössö tavoittaa noin tuhat elektroniikan ja sähkötekniikan opiskelijaa sekä koko tiedekunnan henkilökunnan.
|
||||
Lisäksi lehti lähetetään muille opiskelijajärjestöille. Yritysten on mahdollista saada mainostilaa Sössön sivuilta.
|
||||
</p>
|
||||
</div>
|
||||
@@ -92,16 +92,16 @@ const CorporatePageView: React.FC<CorporatePageViewProps> = ({ jobAds }) => (
|
||||
<TextSection>
|
||||
<h3>Olethan yhteydessä!</h3>
|
||||
<div>
|
||||
<p>Yllämainituista mahdollisuuksista, sekä muista ideoista kiinnostuneena, voit olla yhteydessä Yrityssuhdemestariimme Tommiin.</p>
|
||||
<p>Yllämainituista mahdollisuuksista, sekä muista ideoista kiinnostuneena, voit olla yhteydessä Yrityssuhdemestariimme.</p>
|
||||
<h6>Yrityssuhdemestari</h6>
|
||||
<p>Tommi Oinonen <br />044 299 3439<br /> <a href={`mailto:${CORPORATE_MASTER_MAIL}`}>{CORPORATE_MASTER_MAIL}</a></p>
|
||||
<p>{CORPORATE_MASTER_INFO.name} <br /> <a href={`mailto:${CORPORATE_MASTER_INFO.email}`}>{CORPORATE_MASTER_INFO.email}</a></p>
|
||||
</div>
|
||||
</TextSection>
|
||||
|
||||
<CTASection
|
||||
bgColor="orange1"
|
||||
link="https://sosso.fi/wp-content/uploads/2022/01/sossomediakortti22.pdf"
|
||||
linkText="Killan lehden mediakortin löydät täältä ›"
|
||||
link="https://static.sahkoinsinoorikilta.fi/sekalaista/sossomediakortti25-web.pdf"
|
||||
linkText="Killan lehden mediakortti ›"
|
||||
>
|
||||
Mainos Sössöön?
|
||||
</CTASection>
|
||||
@@ -110,7 +110,7 @@ const CorporatePageView: React.FC<CorporatePageViewProps> = ({ jobAds }) => (
|
||||
<h3 id="tyopaikat">Työpaikkailmoitukset</h3>
|
||||
<div>
|
||||
<JobAdList jobAds={jobAds} />
|
||||
<p>Voit saada yrityksesi työpaikkailmoituksen listalle lähettämällä sen osoitteeseen <a href={`mailto:${CORPORATE_MASTER_MAIL}`}>{CORPORATE_MASTER_MAIL}</a></p>
|
||||
<p> Haluatko työpaikkailmoituksesti näkyviin listalle? Lähetä tarjous osoitteeseen <a href={`mailto:${CORPORATE_MASTER_INFO.email}`}>{CORPORATE_MASTER_INFO.email}</a></p>
|
||||
</div>
|
||||
|
||||
</TextSection>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import JobAd from "@models/JobAd";
|
||||
import { Accordion } from "@components/index";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import rehypeSanitize from "rehype-sanitize";
|
||||
|
||||
interface JobAdListProps {
|
||||
jobAds: JobAd[];
|
||||
}
|
||||
|
||||
const List = styled.ul`
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
margin: 1rem 0;
|
||||
list-style: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const JobAdList: React.FC<JobAdListProps> = ({ jobAds }) => (
|
||||
<List>
|
||||
{jobAds.map((ad) => (
|
||||
<li key={ad.id}>
|
||||
<Accordion title={ad.title_en}>
|
||||
<div>
|
||||
<p>
|
||||
{ad.description_en}
|
||||
</p>
|
||||
<ReactMarkdown rehypePlugins={[rehypeRaw, rehypeSanitize]}>
|
||||
{ad.content_en}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
</Accordion>
|
||||
</li>
|
||||
))}
|
||||
</List>
|
||||
|
||||
);
|
||||
|
||||
export default JobAdList;
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import { TextSection } from "@components/index";
|
||||
|
||||
const EquityPageView: React.FC = () => (
|
||||
<TextSection>
|
||||
<h1>Yhdenvertaisuus</h1>
|
||||
<div>
|
||||
<p>Sähköinsinöörikilta ry on sitoutunut edistämään yhdenvertaisuutta ja tasa-arvoa. Kilta on kaikille avoin ja
|
||||
toivottaa kaikki uudet jäsenet tervetulleiksi toimintaansa. Kilta ei hyväksy minkäänlaista syrjintää, kiusaamista tai häirintää.
|
||||
</p>
|
||||
<p>
|
||||
Mikäli kohtaat epäasiallista käytöstä, voit täyttää <a href="https://docs.google.com/forms/d/e/1FAIpQLSdG4U2gBG25YehNLvor5KP9CRmd83unWtP1-jmd-3e5fCyomQ/viewform">tämän</a> lomakkeen.
|
||||
Löydät oheisesta lomakkeesta myös yhdenvertaisuusvastaavien yhteystiedot.
|
||||
</p>
|
||||
</div>
|
||||
</TextSection>
|
||||
);
|
||||
|
||||
export default EquityPageView;
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Hero, HeroPrimarySection, HeroAside, HeroAsideItem,
|
||||
} from "@components/Hero";
|
||||
|
||||
const ForFreshmenPageHero: React.FC = () => (
|
||||
<Hero>
|
||||
<HeroPrimarySection
|
||||
header="Welcome to study in Otaniemi!"
|
||||
text="This is the frontpage for fuksis (freshmen). Here we have collected all the most important information that you will need during your first year.
|
||||
Of course, everything happening in the guild can't fit here, so it is recommended that you also check out the more general 'in english' page."
|
||||
/>
|
||||
|
||||
<HeroAside bgColor="lightTurquoise">
|
||||
<HeroAsideItem
|
||||
header="Read the guild freshman guide"
|
||||
link="https://static.sahkoinsinoorikilta.fi/FTMK/Fopas_25_en_web.pdf"
|
||||
linkText="read the freshman guide here!"
|
||||
/>
|
||||
|
||||
<HeroAsideItem
|
||||
header="Follow the guild's announcements"
|
||||
link="https://t.me/+KxOI-aQ0jpFhNTJk"
|
||||
linkText="Join the guild's Telegram-group!"
|
||||
/>
|
||||
<HeroAsideItem
|
||||
header="Fuksi groups and ISOs?"
|
||||
link="#isos"
|
||||
linkText="Information about the fuksi groups"
|
||||
/>
|
||||
</HeroAside>
|
||||
</Hero>
|
||||
);
|
||||
|
||||
export default ForFreshmenPageHero;
|
||||
@@ -0,0 +1,169 @@
|
||||
import React from "react";
|
||||
import Image from "next/image";
|
||||
import styled from "styled-components";
|
||||
import {
|
||||
CTASection, TextSection, InfoBox, PageLink, Link,
|
||||
} from "@components/index";
|
||||
import ForFreshmenPageHero from "./ForFreshmenPageHero";
|
||||
|
||||
const FUKSI_POINTS_LINK = "https://static.sahkoinsinoorikilta.fi/FTMK/Fuksipisteohje.pdf";
|
||||
const TG_GROUP_CHAT_LINK = "https://t.me/+ctpg4H0-Y3hlZTY0";
|
||||
const TG_NOTIFICATIONS_LINK = "https://t.me/+v30Nts-MrIMyMjNk";
|
||||
const EMAIL_LINK = "ftmk@sahkoinsinoorikilta.fi";
|
||||
const EMAIL_LINK_MAILTO = `mailto:${EMAIL_LINK}`;
|
||||
|
||||
const ImageContainer = styled.div`
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin: auto;
|
||||
`;
|
||||
|
||||
const QRImages = styled.img`
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
`;
|
||||
|
||||
const FopasImage = styled.img`
|
||||
width: 15em;
|
||||
margin-bottom: 1em;
|
||||
`;
|
||||
|
||||
const ForFreshmenPageView: React.FC = () => (
|
||||
<>
|
||||
<ForFreshmenPageHero />
|
||||
<TextSection>
|
||||
<h3 id="abeille">Congratulations on an awesome choice of studies!</h3>
|
||||
<div>
|
||||
<p>
|
||||
You have made an excellent choice by taking the first step on a journey where you will first become an engineering student, ...known better in finnish
|
||||
as "teekkari" and later a Master of Science in Engineering "Diplomi-insinööri".
|
||||
You have just become a technical high school graduate and a freshman.
|
||||
A great achievement that certainly deserves celebration, and there is no better place for that celebration than Otaniemi.
|
||||
Welcome!
|
||||
</p>
|
||||
<p>
|
||||
As a first step, we recommend that you join the Telegram channels created for freshmen.
|
||||
{" "}
|
||||
<Link to={TG_GROUP_CHAT_LINK} target="_blank">Click here</Link> to get acquainted with your fellow freshmen and ISOs, and <Link to={TG_NOTIFICATIONS_LINK} target="_blank">click here</Link> to join the notification channel.
|
||||
</p>
|
||||
|
||||
<h6>A story named Teekkarius</h6>
|
||||
<p>
|
||||
Every teekkari's journey is unique.
|
||||
The guild, the student union, and the other organizations in Otaniemi will undoubtedly offer something for everyone.
|
||||
You are now part of Aalto University's Electrical Engineering Guild, and we will support you throughout your teekkari journey so that you can find the places that are perfect for you to make an impact and pursue your hobbies.
|
||||
To make this possible, we have placed you in a freshman group, which you will get to know during orientation week and which will serve as your support group for new adventures.
|
||||
Your freshman group also includes a few tutors better known as ISOs.
|
||||
You can find more information about them <Link to="#isot">below</Link>.
|
||||
</p>
|
||||
|
||||
<ImageContainer>
|
||||
<Image
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/IMG_6539.JPG"
|
||||
alt="Kipparit"
|
||||
width={100}
|
||||
height={80}
|
||||
style={{ objectFit: "contain" }}
|
||||
/>
|
||||
</ImageContainer>
|
||||
|
||||
<h6>Freshmen captains</h6>
|
||||
<p>
|
||||
We are your freshman captains <strong>Teemu</strong> and <strong>Henri</strong> and we'll be here to support you and monitor your
|
||||
progress throughout the freshman year adventures toward earning your engineer's hat (= teekkarilakki),
|
||||
which you might possibly earn during May Day next spring.
|
||||
If you have any questions, feel free to contact us via <Link to={TG_GROUP_CHAT_LINK} target="_blank">Telegram</Link> or <a href={EMAIL_LINK_MAILTO}>email</a>.
|
||||
</p>
|
||||
|
||||
<h6>Smile When We Meet!</h6>
|
||||
<p>
|
||||
Although the first days in Otaniemi might bring along some funny and strange experiences, don't be alarmed by them!
|
||||
Over time, the pieces of the puzzle will come together to form an image that reflects you, and you'll have the opportunity to shape what the final result looks like.
|
||||
</p>
|
||||
<p>
|
||||
Orientation week is held from August 25th to 29th, 2025, but even before then, you'll have the chance to meet us, other freshmen, and the ISOs at a relaxed Pre-Start event.
|
||||
The Pre-Start for the freshman year is organized on Saturday, August 16th, 2025. Find more details in the Telegram groups!
|
||||
</p>
|
||||
|
||||
<h6>Teemu Heikkinen</h6>
|
||||
<p>040 097 1835<br />teemu.heikkinen (ät) sahkoinsinoorikilta.fi <br />@heikkinenteemu</p>
|
||||
|
||||
<h6>Henri Aito</h6>
|
||||
<p>045 328 2883<br />henri.aito (ät) sahkoinsinoorikilta.fi <br />@henriaito</p>
|
||||
</div>
|
||||
<aside>
|
||||
<div>
|
||||
<PageLink to={EMAIL_LINK_MAILTO} desc={EMAIL_LINK}>
|
||||
You can reach the freshman captains at
|
||||
</PageLink>
|
||||
<PageLink to="https://api.sahkoinsinoorikilta.fi/members/application" desc="And join our activities! ›">
|
||||
Join the guild!
|
||||
</PageLink>
|
||||
<PageLink to={FUKSI_POINTS_LINK} desc="Take a look at the fuksipoints ›">
|
||||
Fuksipoint guide - This will be translated later so don't worry if you don't understand Finnish!
|
||||
</PageLink>
|
||||
</div>
|
||||
<div>
|
||||
<InfoBox>
|
||||
<h6>Fuksiguide</h6>
|
||||
<Link to="https://static.sahkoinsinoorikilta.fi/FTMK/Fopas_25_en_web.pdf" target="_blank">
|
||||
<FopasImage
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/Fopas_25_kansi.jpg"
|
||||
/>
|
||||
</Link>
|
||||
|
||||
<p>
|
||||
It's a good idea to take a look at the fuksiguide before starting your studies!
|
||||
The guide contains lots of useful information about the guild, the student union, and the student life in Otaniemi.
|
||||
You can find the guide <Link to="https://static.sahkoinsinoorikilta.fi/FTMK/Fopas_25_en_web.pdf" target="_blank">here</Link>.
|
||||
</p>
|
||||
<br />
|
||||
<h6>Telegram?</h6>
|
||||
<p>
|
||||
Telegram is a messaging app used in Otaniemi.
|
||||
More info can be found here: <Link to="https://telegram.org/faq" target="_blank">https://telegram.org/faq</Link>.
|
||||
</p>
|
||||
<p>
|
||||
SIK fuksis have a group chat, which you can join by scanning the QR code below:
|
||||
</p>
|
||||
<QRImages
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/SIK-Fuksit-2025.jpg"
|
||||
/>
|
||||
<p>or <Link to={TG_GROUP_CHAT_LINK} target="_blank">press me!</Link></p>
|
||||
<p>Also join the notifications channel for SIK fuksis, to stay in the loop!:</p>
|
||||
<QRImages
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/SIK-Fuksit-tiedotus-2025.jpg"
|
||||
/>
|
||||
<p>or <Link to={TG_NOTIFICATIONS_LINK} target="_blank">press me!</Link></p>
|
||||
</InfoBox>
|
||||
</div>
|
||||
</aside>
|
||||
</TextSection>
|
||||
<CTASection
|
||||
bgColor="lightBlue"
|
||||
link="/kilta/toiminta"
|
||||
linkText="Follow what the guild is up to"
|
||||
>
|
||||
The guild organises lots of things!
|
||||
</CTASection>
|
||||
|
||||
<TextSection>
|
||||
<h3 id="isos">Freshman groups and ISOs</h3>
|
||||
<div>
|
||||
<p>SIK freshmen enjoy the guidance and care of their wonderful ISOs in their own freshman groups</p>
|
||||
<p>
|
||||
ISOs are older students and guild members, who are there to support you throughout your freshman year. You will be divided into groups.
|
||||
You can ask your ISOs anything regarding studying and student life. Even though they don't know all the answers, they can likely help you finding them.
|
||||
</p>
|
||||
<p>
|
||||
As stated above, your ISOs will support you through your whole freshman year, but you will see them most during the orientation week,
|
||||
during which they will wander through Otaniemi together with your group and guide you into the ways of the teekkari.
|
||||
They will also help you find whatever is needed to start your studies here, and will support you in creating your timetable and getting your library, HSL and student cards.
|
||||
</p>
|
||||
<p>ISOs are also invited to the first event of the freshman year, the head start. Come meet them there early!</p>
|
||||
</div>
|
||||
</TextSection>
|
||||
</>
|
||||
);
|
||||
|
||||
export default ForFreshmenPageView;
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Hero, HeroPrimarySection, HeroAside, HeroAsideItem,
|
||||
} from "@components/Hero";
|
||||
|
||||
const ForFreshmenPageHero: React.FC = () => (
|
||||
<Hero>
|
||||
<HeroPrimarySection
|
||||
header="Welcome to Aalto and Otaniemi!"
|
||||
text="This is the frontpage for fuksis (freshmen). Here we have collected all the most important information that you will need during your first year.
|
||||
Of course, everything happening in the guild can't fit here, so it is recommended that you also check out the more general 'in english' page."
|
||||
/>
|
||||
|
||||
<HeroAside bgColor="lightTurquoise">
|
||||
<HeroAsideItem
|
||||
header="Read the guild's fuksi guide"
|
||||
link="https://static.sahkoinsinoorikilta.fi/FTMK/Fopas_25_en_web.pdf"
|
||||
linkText="Read the fuksi guide here!"
|
||||
/>
|
||||
|
||||
<HeroAsideItem
|
||||
header="Follow the guild's announcements"
|
||||
link="https://t.me/+KxOI-aQ0jpFhNTJk"
|
||||
linkText="Join the guild's Telegram group!"
|
||||
/>
|
||||
<HeroAsideItem
|
||||
header="Fuksi groups and ISOs?"
|
||||
link="#isos"
|
||||
linkText="Information about the fuksi groups"
|
||||
/>
|
||||
</HeroAside>
|
||||
</Hero>
|
||||
);
|
||||
|
||||
export default ForFreshmenPageHero;
|
||||
@@ -0,0 +1,190 @@
|
||||
import React from "react";
|
||||
import Image from "next/image";
|
||||
import styled from "styled-components";
|
||||
import {
|
||||
CTASection, TextSection, InfoBox, PageLink, Link,
|
||||
} from "@components/index";
|
||||
import ForIntlPageHero from "./ForIntlPageHero";
|
||||
|
||||
const FUKSI_POINTS_LINK = "https://static.sahkoinsinoorikilta.fi/FTMK/Fuksipisteohje.pdf";
|
||||
const TG_GROUP_CHAT_LINK = "https://t.me/+oNrBDLI5cXZhNDEx";
|
||||
const TG_NOTIFICATIONS_LINK = "https://t.me/sikhotline2526";
|
||||
const EMAIL_LINK = "ftmk@sahkoinsinoorikilta.fi";
|
||||
const EMAIL_LINK_MAILTO = `mailto:${EMAIL_LINK}`;
|
||||
|
||||
const ImageContainer = styled.div`
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin: auto;
|
||||
`;
|
||||
|
||||
const QRImages = styled.img`
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
`;
|
||||
|
||||
const FopasImage = styled.img`
|
||||
width: 15em;
|
||||
margin-bottom: 1em;
|
||||
`;
|
||||
|
||||
const ForIntlPageView: React.FC = () => (
|
||||
<>
|
||||
<ForIntlPageHero />
|
||||
<TextSection>
|
||||
<h3 id="abeille">Congratulations on your admission!</h3>
|
||||
<div>
|
||||
<p>
|
||||
You've not only become a new student at Aalto, but also what's known as a teekkari
|
||||
– a term used to describe students of technology in Finland, and which is synonymous
|
||||
with a distinct, tradition-filled student culture.
|
||||
</p>
|
||||
<p>
|
||||
Whether you've learned about this before or it's your first time hearing about it, it's absolutely worth celebrating, and the best place for this is definitely our campus in Otaniemi. Welcome!
|
||||
</p>
|
||||
<p>
|
||||
As a first step, we recommend that you join the Telegram channels made for fuksis. This is where you can get to know your fellow new students and your student tutors known as ISOs. This is also where you can access the information channel.
|
||||
{" "}
|
||||
<Link to={TG_GROUP_CHAT_LINK} target="_blank">Click here</Link> to get acquainted with your fellow freshmen and ISOs, and <Link to={TG_NOTIFICATIONS_LINK} target="_blank">click here</Link> to join the notification channel.
|
||||
</p>
|
||||
|
||||
<h6>A journey called Teekkarius</h6>
|
||||
<p>
|
||||
Every teekkari's journey is unique.
|
||||
The guild, the student union, and the other organizations in Otaniemi will undoubtedly offer something for everyone.
|
||||
You are now part of Aalto University's Electrical Engineering Guild, and we will support you throughout your teekkari journey so that you can find the places that are perfect for you to make an impact and pursue your hobbies.
|
||||
To make this possible, we have placed you in a freshman group, which you will get to know during orientation week and which will serve as your support group for new adventures.
|
||||
Your freshman group also includes a few tutors better known as ISOs.
|
||||
You can find more information about them <Link to="#isot">below</Link>.
|
||||
</p>
|
||||
<p>
|
||||
The journey of a teekkari is unique to everyone. The guild, the Aalto Student Union,
|
||||
and other organizations in Otaniemi offer various opportunities to pursue hobbies,
|
||||
passions, and social lives.
|
||||
</p>
|
||||
<p>
|
||||
You are now part of the Aalto University Guid of Electrical Engineering
|
||||
(SIK, short for Sähköinsinöörikilta in Finnish) and we will support you in
|
||||
settling in and finding the right places to have fun and make an impact.
|
||||
</p>
|
||||
<p>
|
||||
To make this successful, we’ve placed you in a small “fuksi group” with other new students,
|
||||
whom you will get to know and adventure with starting in Orientation Week.
|
||||
Your fuksi group also includes a few ISOs, who have studied here for at least a year and will
|
||||
lean on their experience to show you around and help you get comfortable.
|
||||
</p>
|
||||
|
||||
<ImageContainer>
|
||||
<Image
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/Captains2025.jpg"
|
||||
alt="Kipparit"
|
||||
width={100}
|
||||
height={80}
|
||||
style={{ objectFit: "contain" }}
|
||||
/>
|
||||
</ImageContainer>
|
||||
|
||||
<h6>International captains</h6>
|
||||
<p>
|
||||
We are your International Fuksi Captains <strong>Markus</strong> and <strong>Apollo</strong>,
|
||||
and we will be there to support you in getting started at Aalto, but also to guide you through
|
||||
the awesome (and distinctly Finnish) process of becoming a full-blown teekkari.
|
||||
This involves participating in many fun activities and traditions, culminating in earning the famous
|
||||
Teekkari Cap and having an amazing community alongside you. If you have any questions,
|
||||
please contact us on Telegram or by email.
|
||||
</p>
|
||||
|
||||
<h6>Looking forward to meeting you!</h6>
|
||||
<p>
|
||||
Even though your first few days in Otaniemi may bring some new and unfamiliar experiences,
|
||||
please don't be intimidated! Over time, the pieces of the puzzle will come together and you'll be
|
||||
having just as much fun as we are. Always remember that as a teekkari in Otaniemi, you're never alone.
|
||||
</p>
|
||||
<p>
|
||||
Orientation week will be held from 25 to 29 August 2025, but even before that you have the
|
||||
opportunity to come and get to know us, other freshmen and ISOs at a relaxed Headstart event.
|
||||
This will be held on Saturday 16 August 2025. More about that in the Telegram groups!
|
||||
</p>
|
||||
|
||||
<h6>Apollo Ailus</h6>
|
||||
<p>+358 045 803 3662<br />apollo.ailus@sahkoinsinoorikilta.fi <br />@SIKCaptain</p>
|
||||
|
||||
<h6>Markus Aaltio</h6>
|
||||
<p>+358 044 050 4028<br />markus.aaltio@sahkoinsinoorikilta.fi <br />@KvCaptain</p>
|
||||
</div>
|
||||
<aside>
|
||||
<div>
|
||||
<PageLink to={EMAIL_LINK_MAILTO} desc={EMAIL_LINK}>
|
||||
You can reach the freshman captains at
|
||||
</PageLink>
|
||||
<PageLink to="https://api.sahkoinsinoorikilta.fi/members/application" desc="And join our activities! ›">
|
||||
Join the guild!
|
||||
</PageLink>
|
||||
<PageLink to={FUKSI_POINTS_LINK} desc="Take a look at the fuksipoints ›">
|
||||
Fuksipoint guide - This will be translated later so don't worry if you don't understand Finnish!
|
||||
</PageLink>
|
||||
</div>
|
||||
<div>
|
||||
<InfoBox>
|
||||
<h6>Fuksiguide</h6>
|
||||
<Link to="https://static.sahkoinsinoorikilta.fi/FTMK/Fuksiguide_25_web.pdf" target="_blank">
|
||||
<FopasImage
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/Fuksiguide_25_cover.png"
|
||||
/>
|
||||
</Link>
|
||||
|
||||
<p>
|
||||
It's a good idea to take a look at the fuksiguide before starting your studies!
|
||||
The guide contains lots of useful information about the guild, the student union, and the student life in Otaniemi.
|
||||
You can find the guide <Link to="https://static.sahkoinsinoorikilta.fi/FTMK/Fopas_25_en_web.pdf" target="_blank">here</Link>.
|
||||
</p>
|
||||
<br />
|
||||
<h6>Telegram?</h6>
|
||||
<p>
|
||||
Telegram is a messaging app used in Otaniemi.
|
||||
More info can be found here: <Link to="https://telegram.org/faq" target="_blank">https://telegram.org/faq</Link>.
|
||||
</p>
|
||||
<p>
|
||||
SIK fuksis have a group chat, which you can join by scanning the QR code below:
|
||||
</p>
|
||||
<QRImages
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/SIK-Fuksit-2025.jpg"
|
||||
/>
|
||||
<p>or <Link to={TG_GROUP_CHAT_LINK} target="_blank">press me!</Link></p>
|
||||
<p>Also join the notifications channel for SIK fuksis, to stay in the loop!:</p>
|
||||
<QRImages
|
||||
src="https://static.sahkoinsinoorikilta.fi/FTMK/SIK-Fuksit-tiedotus-2025.jpg"
|
||||
/>
|
||||
<p>or <Link to={TG_NOTIFICATIONS_LINK} target="_blank">press me!</Link></p>
|
||||
</InfoBox>
|
||||
</div>
|
||||
</aside>
|
||||
</TextSection>
|
||||
<CTASection
|
||||
bgColor="lightBlue"
|
||||
link="/kilta/toiminta"
|
||||
linkText="Follow what the guild is up to"
|
||||
>
|
||||
The guild organises lots of things!
|
||||
</CTASection>
|
||||
|
||||
<TextSection>
|
||||
<h3 id="isos">Freshman groups and ISOs</h3>
|
||||
<div>
|
||||
<p>SIK freshmen enjoy the guidance and care of their wonderful ISOs in their own freshman groups</p>
|
||||
<p>
|
||||
ISOs are older students and guild members, who are there to support you throughout your freshman year. You will be divided into groups.
|
||||
You can ask your ISOs anything regarding studying and student life. Even though they don't know all the answers, they can likely help you finding them.
|
||||
</p>
|
||||
<p>
|
||||
As stated above, your ISOs will support you through your whole freshman year, but you will see them most during the orientation week,
|
||||
during which they will wander through Otaniemi together with your group and guide you into the ways of the teekkari.
|
||||
They will also help you find whatever is needed to start your studies here, and will support you in creating your timetable and getting your library, HSL and student cards.
|
||||
</p>
|
||||
<p>ISOs are also invited to the first event of the freshman year, the head start. Come meet them there early!</p>
|
||||
</div>
|
||||
</TextSection>
|
||||
</>
|
||||
);
|
||||
|
||||
export default ForIntlPageView;
|
||||
@@ -13,24 +13,24 @@ const FreshmenPageHero: React.FC = () => (
|
||||
<HeroAside bgColor="lightTurquoise">
|
||||
<HeroAsideItem
|
||||
header="Lue killan fuksiopas"
|
||||
link="https://static.sahkoinsinoorikilta.fi/FTMK/Fuksiopas2022.pdf"
|
||||
link="https://static.sahkoinsinoorikilta.fi/FTMK/Fopas_25_web.pdf"
|
||||
linkText="lue fuksiopas täältä!"
|
||||
/>
|
||||
|
||||
<HeroAsideItem
|
||||
header="Seuraa killan tiedotusta"
|
||||
link="https://t.me/+ubTeGSYKTvg3NmVk"
|
||||
linkText="Liity killan Telegram-ryhmiin"
|
||||
link="https://t.me/+KxOI-aQ0jpFhNTJk"
|
||||
linkText="Liity killan Telegram-ryhmään!"
|
||||
/>
|
||||
<HeroAsideItem
|
||||
header="Kaikki kunnossa opiskelua varten?"
|
||||
link="https://into.aalto.fi/pages/viewpage.action?pageId=1183171"
|
||||
link="https://www.aalto.fi/fi/ohjelmat/sahkotekniikan-kandidaattiohjelma/opintojen-aloittaminen"
|
||||
linkText="Lue korkeakoulun tietopaketti"
|
||||
/>
|
||||
<HeroAsideItem
|
||||
header="ISO-ryhmät ja ISO-henkilöt?"
|
||||
header="Fuksiryhmät ja ISOt?"
|
||||
link="#isot"
|
||||
linkText="Tsekkaa ISO-henkilöiden tiedot"
|
||||
linkText="Tietoa fuksiryhmistä"
|
||||
/>
|
||||
</HeroAside>
|
||||
</Hero>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user