Redesign page + Webhook notifications #43

Merged
ldr merged 16 commits from facelift into main 2023-12-25 21:23:53 +01:00
42 changed files with 850 additions and 299 deletions

View file

@ -1,3 +1,5 @@
Bennet Bleßmann <ben@fs-infmat.uni-kiel.de>
Bennet Bleßmann <ben@fs-infmat.uni-kiel.de> <bennet.blessmann+github@googlemail.com>
Bennet Bleßmann <ben@fs-infmat.uni-kiel.de> <bb-github@t-online.de>
Lukas Drescher <ldr@fs-informatik.uni-kiel.de>
Lukas Drescher <ldr@fs-informatik.uni-kiel.de> JustAnotherJavaProgrammer <29919508+JustAnotherJavaProgrammer@users.noreply.github.com>

409
Cargo.lock generated
View file

@ -8,7 +8,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"bytes",
"futures-core",
"futures-sink",
@ -30,7 +30,7 @@ dependencies = [
"actix-utils",
"actix-web",
"askama_escape",
"bitflags",
"bitflags 1.3.2",
"bytes",
"derive_more",
"futures-core",
@ -44,17 +44,17 @@ dependencies = [
[[package]]
name = "actix-http"
version = "3.3.0"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0070905b2c4a98d184c4e81025253cb192aa8a73827553f38e9410801ceb35bb"
checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9"
dependencies = [
"actix-codec",
"actix-rt",
"actix-service",
"actix-utils",
"ahash",
"ahash 0.8.6",
"base64 0.21.0",
"bitflags",
"bitflags 2.4.1",
"brotli",
"bytes",
"bytestring",
@ -88,7 +88,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6"
dependencies = [
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -178,6 +178,28 @@ dependencies = [
"tracing",
]
[[package]]
name = "actix-tls"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72616e7fbec0aa99c6f3164677fa48ff5a60036d0799c98cab894a44f3e0efc3"
dependencies = [
"actix-rt",
"actix-service",
"actix-utils",
"futures-core",
"http",
"impl-more",
"pin-project-lite",
"rustls 0.21.10",
"rustls-webpki",
"tokio",
"tokio-rustls",
"tokio-util",
"tracing",
"webpki-roots",
]
[[package]]
name = "actix-utils"
version = "3.0.1"
@ -203,7 +225,7 @@ dependencies = [
"actix-service",
"actix-utils",
"actix-web-codegen",
"ahash",
"ahash 0.7.6",
"bytes",
"bytestring",
"cfg-if",
@ -238,7 +260,7 @@ dependencies = [
"actix-router",
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -293,6 +315,19 @@ dependencies = [
"version_check",
]
[[package]]
name = "ahash"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "0.7.20"
@ -362,7 +397,7 @@ checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
"synstructure",
]
@ -374,7 +409,7 @@ checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -385,7 +420,7 @@ checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -405,6 +440,40 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "awc"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fa3c705a9c7917ac0f41c0757a0a747b43bbc29b0b364b081bd7c5fc67fb223"
dependencies = [
"actix-codec",
"actix-http",
"actix-rt",
"actix-service",
"actix-tls",
"actix-utils",
"base64 0.21.0",
"bytes",
"cfg-if",
"cookie",
"derive_more",
"futures-core",
"futures-util",
"h2",
"http",
"itoa",
"log",
"mime",
"percent-encoding",
"pin-project-lite",
"rand",
"rustls 0.20.8",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
]
[[package]]
name = "base64"
version = "0.13.1"
@ -425,7 +494,7 @@ checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
[[package]]
name = "better_toml_datetime"
version = "0.3.0"
version = "0.4.0"
dependencies = [
"serde",
"thiserror",
@ -438,6 +507,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "block-buffer"
version = "0.10.3"
@ -629,7 +704,7 @@ version = "4.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"clap_derive",
"clap_lex",
"is-terminal",
@ -648,7 +723,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -772,7 +847,7 @@ dependencies = [
"proc-macro2",
"quote",
"scratch",
"syn",
"syn 1.0.107",
]
[[package]]
@ -789,7 +864,7 @@ checksum = "357f40d1f06a24b60ae1fe122542c1fb05d28d32acb2aed064e84bc2ad1e252e"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -822,7 +897,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"syn",
"syn 1.0.107",
]
[[package]]
@ -833,9 +908,9 @@ checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
[[package]]
name = "digest"
version = "0.10.6"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
@ -850,7 +925,7 @@ checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -897,6 +972,12 @@ dependencies = [
"termcolor",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.2.8"
@ -1008,7 +1089,7 @@ checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -1078,7 +1159,7 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"libc",
"libgit2-sys",
"log",
@ -1087,9 +1168,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.3.15"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178"
dependencies = [
"bytes",
"fnv",
@ -1097,7 +1178,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
"indexmap",
"indexmap 2.1.0",
"slab",
"tokio",
"tokio-util",
@ -1125,6 +1206,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "heck"
version = "0.3.3"
@ -1268,6 +1355,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "impl-more"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d"
[[package]]
name = "indexmap"
version = "1.9.2"
@ -1275,7 +1368,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
"hashbrown 0.12.3",
]
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown 0.14.3",
]
[[package]]
@ -1303,7 +1406,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.42.0",
]
[[package]]
@ -1315,7 +1418,7 @@ dependencies = [
"hermit-abi 0.2.6",
"io-lifetimes",
"rustix",
"windows-sys",
"windows-sys 0.42.0",
]
[[package]]
@ -1335,12 +1438,14 @@ checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "jobboerse"
version = "0.3.0"
version = "0.4.0"
dependencies = [
"actix-files",
"actix-multipart",
"actix-session",
"actix-tls",
"actix-web",
"awc",
"better_toml_datetime",
"cargo-bundle-licenses",
"chrono",
@ -1420,8 +1525,8 @@ dependencies = [
"log",
"nom",
"percent-encoding",
"ring",
"rustls",
"ring 0.16.20",
"rustls 0.20.8",
"rustls-native-certs",
"thiserror",
"tokio",
@ -1592,12 +1697,12 @@ dependencies = [
"libc",
"log",
"wasi",
"windows-sys",
"windows-sys 0.42.0",
]
[[package]]
name = "multipart_helper"
version = "0.3.0"
version = "0.4.0"
dependencies = [
"actix-multipart",
"futures-util",
@ -1718,7 +1823,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-sys",
"windows-sys 0.42.0",
]
[[package]]
@ -1772,7 +1877,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -1879,7 +1984,7 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
"version_check",
]
@ -1896,9 +2001,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.50"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
dependencies = [
"unicode-ident",
]
@ -1911,9 +2016,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.23"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
@ -1960,7 +2065,7 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@ -1998,12 +2103,26 @@ dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"spin 0.5.2",
"untrusted 0.7.1",
"web-sys",
"winapi",
]
[[package]]
name = "ring"
version = "0.17.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e"
dependencies = [
"cc",
"getrandom",
"libc",
"spin 0.9.8",
"untrusted 0.9.0",
"windows-sys 0.48.0",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
@ -2028,12 +2147,12 @@ version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.42.0",
]
[[package]]
@ -2043,11 +2162,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
dependencies = [
"log",
"ring",
"ring 0.16.20",
"sct",
"webpki",
]
[[package]]
name = "rustls"
version = "0.21.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
dependencies = [
"log",
"ring 0.17.3",
"rustls-webpki",
"sct",
]
[[package]]
name = "rustls-native-certs"
version = "0.6.2"
@ -2069,6 +2200,16 @@ dependencies = [
"base64 0.21.0",
]
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring 0.17.3",
"untrusted 0.9.0",
]
[[package]]
name = "ryu"
version = "1.0.12"
@ -2090,7 +2231,7 @@ version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
dependencies = [
"windows-sys",
"windows-sys 0.42.0",
]
[[package]]
@ -2111,8 +2252,8 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
"ring 0.16.20",
"untrusted 0.7.1",
]
[[package]]
@ -2121,7 +2262,7 @@ version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c4437699b6d34972de58652c68b98cb5b53a4199ab126db8e20ec8ded29a721"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"core-foundation",
"core-foundation-sys",
"libc",
@ -2164,7 +2305,7 @@ checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -2205,7 +2346,7 @@ version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
dependencies = [
"indexmap",
"indexmap 1.9.2",
"ryu",
"serde",
"yaml-rust",
@ -2297,6 +2438,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "strsim"
version = "0.10.0"
@ -2321,14 +2468,14 @@ dependencies = [
"heck 0.3.3",
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
name = "subtle"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
@ -2341,6 +2488,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "synstructure"
version = "0.12.6"
@ -2349,7 +2507,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
"unicode-xid",
]
@ -2393,7 +2551,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -2454,7 +2612,7 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
"windows-sys 0.42.0",
]
[[package]]
@ -2465,7 +2623,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
]
[[package]]
@ -2474,7 +2632,7 @@ version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls",
"rustls 0.20.8",
"tokio",
"webpki",
]
@ -2540,7 +2698,7 @@ version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233d8716cdc5d20ec88a18a839edaf545edc71efa4a5ff700ef4a102c26cd8fa"
dependencies = [
"indexmap",
"indexmap 1.9.2",
"nom8",
"serde",
"serde_spanned",
@ -2630,9 +2788,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "universal-hash"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [
"crypto-common",
"subtle",
@ -2644,6 +2802,12 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.3.1"
@ -2706,7 +2870,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
"wasm-bindgen-shared",
]
@ -2728,7 +2892,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.107",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -2755,8 +2919,17 @@ version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
dependencies = [
"ring",
"untrusted",
"ring 0.16.20",
"untrusted 0.7.1",
]
[[package]]
name = "webpki-roots"
version = "0.22.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
dependencies = [
"webpki",
]
[[package]]
@ -2796,13 +2969,37 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.42.1",
"windows_aarch64_msvc 0.42.1",
"windows_i686_gnu 0.42.1",
"windows_i686_msvc 0.42.1",
"windows_x86_64_gnu 0.42.1",
"windows_x86_64_gnullvm 0.42.1",
"windows_x86_64_msvc 0.42.1",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
@ -2811,42 +3008,84 @@ version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "x509-parser"
version = "0.14.0"
@ -2874,6 +3113,26 @@ dependencies = [
"linked-hash-map",
]
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.42",
]
[[package]]
name = "zstd"
version = "0.12.2+zstd.1.5.2"

View file

@ -2,7 +2,7 @@
members = [".", "packages/*"]
[workspace.package]
version = "0.3.0"
version = "0.4.0"
edition = "2021"
rust-version = "1.64"
license = "MIT OR Apache-2.0"
@ -15,7 +15,9 @@ readme = "README.md"
actix-files = "0.6.2"
actix-web = "4.3.0"
actix-session = { version = "0.7.2", features = ["cookie-session"] }
actix-tls = "3.1.1"
actix-multipart = "0.5.0"
awc ={ version = "3.2.0", features = ["rustls"] }
better_toml_datetime = { path = "packages/better_toml_datetime" }
cargo-bundle-licenses = { version = "1.0.1", default-features = false }
chrono = { version = "0.4.23", default-features = false, features = ["std","clock"] }

View file

@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- basic (Discord) webhook support (send message when an offer is made public)
- `webhook_url` option in the config file to specify a complete webhook url
### Fix
- spelling mistakes in e-mail notifications
- spelling mistakes on the website
### Change
- rephrase e-mail notifications
- rephrase texts on the website
- translate all text to German
- update the FAQ
- change the design of the website
### Removed
- reference to `./scripts/adjust_thirdparty.sh` in `README.md` as it no longer exists
## [0.3.0]
### Fix

View file

@ -13,9 +13,6 @@ The minimum required rust-toolchain version as of writing is `1.58` see the `rus
A stable toolchain is recommended.
It is recommended to use cargo for building as such make sure the `cargo` component of the toolchain is installed.
It may be necessary to run `./scripts/adjust_thirdparty.sh` to adjust some absolute paths in the `THIRDPARTY.toml`,
though this should only be required to run tests.
For a release build you can run `cargo build --release` this should build all dependencies and place the final binary in
the `./target/release/` folder.
@ -63,6 +60,7 @@ The expected fields are defined by the `ProgramConfig` struct in `./src/server_c
| `banner` | false | no banner |
| `login_provider` | true | N/A |
| `email` | false | no email |
| `webhook_url` | false | no webhook |
Note: when email is not configured, no confirmation e-mails will be sent, but confirmation is still required!

View file

@ -22,7 +22,9 @@ dev_mode = []
actix-files = { workspace = true }
actix-web = { workspace = true }
actix-session = { workspace = true, features = ["cookie-session"] }
actix-tls = { workspace = true }
actix-multipart = { workspace = true }
awc = { workspace = true }
better_toml_datetime = { workspace = true }
cargo-bundle-licenses = { workspace = true, default-features = false }
chrono = { workspace = true, default-features = false, features = ["std","clock"] }

BIN
packages/jobboerse/THIRDPARTY.toml (Stored with Git LFS)

Binary file not shown.

View file

@ -1,5 +1,6 @@
url_base_path = "jobbörse"
banner = "Hinweis: Die Jobbörse wird aktuall noch evaluiert und befindet sich noch nicht im produktiven Betrieb!"
webhook_url="https://discord.com/api/webhooks/1188255966655946854/UgX-gtkThowrhk4kFdzVc46V5YfAUc_In5U6Ez5YvZhMKKJWCFLjdtBlTJ0nL--kt3GI?wait=true"
[login_provider]
type = 'Development'

View file

@ -6,7 +6,7 @@ use handlebars::Handlebars;
use lettre::message::header::{Header, HeaderName, HeaderValue, UserAgent};
use lettre::message::{Mailbox, SinglePart};
use lettre::{Address, AsyncTransport};
use log::{warn, debug};
use log::{debug, warn};
use serde_json::json;
use url::Url;

View file

@ -30,6 +30,7 @@ mod route;
mod server_config;
mod template;
mod util;
mod webhook;
// internal imports
use crate::job_offers::JobOffers;
@ -155,8 +156,8 @@ async fn run() -> Result<(), error::SeverInitializationError> {
server
.bind([ipv6, ipv4].as_slice())
.map_err(SeverInitializationError::Bind)?
.run()
.await
.map_err(SeverInitializationError::Run)?;
.run()
.await
.map_err(SeverInitializationError::Run)?;
Ok(())
}

View file

@ -9,6 +9,7 @@ use crate::job_offers::view::JobOfferViewData;
use crate::route::job_offer::error::ConfirmationResponseError;
use crate::route::job_offer::error::ConfirmationResponseError::SuccessRenderError;
use crate::route::HTML_CONTENT;
use crate::webhook::{send_new_offer_message, NewOfferWebhookData};
use crate::{get, template, JobOffers, ServerConfig};
#[derive(Serialize)]
@ -101,6 +102,20 @@ pub(crate) async fn confirm_joboffer_post(
Ok(()) => {
job_offer.try_clean().await?;
match &config.config.webhook_url {
Some(webhook_url) if job_offer.is_published() => {
let data = NewOfferWebhookData {
title: job_offer.title.to_owned(),
company: job_offer.offering_party.to_owned(),
link: job_offer.highlight_link(&req)?,
};
send_new_offer_message(&hb, webhook_url.to_owned(), &data)
.await
.ok();
}
_ => {}
};
let data = json!({
"base": crate::route::base(&req, &config, "Job Offer Confirmation Successful")?,
"user": user,

View file

@ -153,8 +153,7 @@ pub(crate) async fn edit_joboffer_post(
if let Some(tmp_file) = file {
// TODO error handling
let _todo =
tmp_file.persist(job_offer_folder.join(&offer.attachment_location));
let _todo = tmp_file.persist(job_offer_folder.join(&offer.attachment_location));
}
Some(offer)

View file

@ -5,6 +5,7 @@ use handlebars::Handlebars;
use crate::email::PublishNoticeEmailData;
use crate::route::job_offer::error::StateChangeResponseError;
use crate::route::JOBOFFER_OVERVIEW_ROUTE;
use crate::webhook::NewOfferWebhookData;
use crate::{auth, JobOffers, ServerConfig};
pub(crate) const JOBOFFER_PUBLISH_ROUTE: &str = "review_offer";
@ -41,6 +42,16 @@ pub(crate) async fn review_joboffer(
)
.await?;
}
if let Some(webhook_url) = &config.config.webhook_url {
let data = NewOfferWebhookData {
title: entry.title.to_owned(),
company: entry.offering_party.to_owned(),
link: entry.highlight_link(&req)?,
};
crate::webhook::send_new_offer_message(&hb, webhook_url.to_owned(), &data)
ldr marked this conversation as resolved

Not aborting because the webhook failed is what I would expect, but it might be good to log the error instead of just ignoring it.

Not aborting because the webhook failed is what I would expect, but it might be good to log the error instead of just ignoring it.

This is now being logged directly inside the function.

This is now being logged directly inside the function.
.await
.ok();
}
}
}

View file

@ -37,6 +37,8 @@ pub(crate) struct ProgramConfig {
pub(crate) login_provider: LoginProviderConfig,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub(crate) email: Option<EmailConfig>,
#[serde(default)]
pub(crate) webhook_url: Option<Url>,
}
#[derive(Serialize, Deserialize, Debug)]

View file

@ -14,3 +14,5 @@ pub(crate) const LICENCES: &str = "licenses";
pub const EMAIL_CONFIRMATION_PLAIN: &str = "email/confirmation_plaintext";
pub const EMAIL_PUBLISH_NOTICE_PLAIN: &str = "email/publish_notice_plaintext";
pub const EMAIL_REVIEWER_NOTICE: &str = "email/reviewer_notice_plaintext";
pub const WEBHOOK_NEW_OFFER_MESSAGE: &str = "webhook/newoffer";

View file

@ -59,8 +59,8 @@ pub fn chrono_datetime_to_toml_datetime<Tz: chrono::TimeZone>(
}
pub fn toml_date_to_chrono_date(date: &toml::value::Date) -> chrono::DateTime<FixedOffset> {
let local_date =
NaiveDate::from_ymd_opt(date.year.into(), date.month.into(), date.day.into()).expect("toml should contain valid date");
let local_date = NaiveDate::from_ymd_opt(date.year.into(), date.month.into(), date.day.into())
.expect("toml should contain valid date");
let offset = chrono_tz::Europe::Berlin
.offset_from_local_date(&local_date)
.map(|offset| offset.fix())
@ -91,13 +91,15 @@ pub fn toml_datetime_to_chrono_datetime(
toml_date.year.into(),
toml_date.month.into(),
toml_date.day.into(),
).expect("toml should contain valid date")
)
.expect("toml should contain valid date")
.and_hms_nano_opt(
toml_time.hour.into(),
toml_time.minute.into(),
toml_time.second.into(),
toml_time.nanosecond,
).expect("toml should contain valid time");
)
.expect("toml should contain valid time");
let offset: FixedOffset = datetime
.offset

View file

@ -0,0 +1,68 @@
use std::sync::Arc;
use actix_tls::connect::rustls_0_20::reexports::ClientConfig;
use awc::{Client, Connector};
use handlebars::{Handlebars, RenderError};
use log::{debug, error, warn};
use serde_json::json;
use url::Url;
use crate::template;
#[derive(serde::Serialize)]
pub(crate) struct NewOfferWebhookData {
pub(crate) title: String,
pub(crate) company: String,
pub(crate) link: Url,
}
pub(crate) async fn send_new_offer_message(
hb: &Handlebars<'_>,
webhook_url: Url,
data: &NewOfferWebhookData,
) -> Result<bool, RenderError> {
let message_text = hb
.render(template::WEBHOOK_NEW_OFFER_MESSAGE, data)
.map_err(|err| {
warn!(
"Rendering webhook message failed with the following error: {}",
err
);
err
})?;
let msg = json!({
"content": message_text,
// We don't accidentally want to mention anybody
"allowed_mentions": {
"parse": []
}
});
debug!("Sending webhook request to {}", webhook_url);
let tls_config = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(actix_tls::connect::rustls::webpki_roots_cert_store())
.with_no_client_auth();
let arc = Arc::new(tls_config);
let connector = Connector::new().rustls(arc);
let client = Client::builder().connector(connector).finish();
let request_result = client.post(webhook_url.as_str()).send_json(&msg).await;
let success = match request_result {
Ok(response) => {
debug!(
"Webhook request succeeded with status: {}",
response.status(),
// make response mutable when uncommenting this
// String::from_utf8(response.body().await.unwrap().to_vec()).unwrap()
);
true
}
Err(err) => {
warn!("Webhook request failed with error: {}", err);
false
}
};
Ok(success)
}

View file

@ -1,40 +1,126 @@
:root {
--header-footer-color: AliceBlue;
--filter-bar-color: Aquamarine;
font-family: "FreeSans", sans-serif;
--green: #87d38b;
--blue: #8ab9e7;
--yellow: #e9a12f;
--light-green: #c3e9c5;
--dark-green: #27682a;
--light-blue: #cce0f5;
--dark-blue: #1c5287;
--light-yellow: #f7deb6;
--dark-yellow: #a66d11;
--default-padding: calc((5 / 16) * 1rem)
}
.header, .footer, .header-banner {
.header, .header-inner, .header-banner {
display: flex;
background: var(--header-footer-color);
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100%;
padding: 5px;
box-shadow: 0px 0px 10px 0px gray;
}
.header-inner, .header-banner {
background: var(--light-green);
padding: var(--default-padding);
}
.header, .header-inner {
flex-direction: column;
}
.header::after {
content: "";
background-color: var(--light-green);
clip-path: polygon(100% 0%, 0% 0%, 0% 100%);
width: 100%;
height: min(5vh, 2.5rem);
}
.header h1 {
padding: var(--default-padding);
margin: 0;
}
a {
color: var(--dark-blue);
text-decoration: none;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.5rem;
}
h3 {
font-size: 1.17rem;
}
.menu {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: baseline;
gap: var(--default-padding);
align-self: stretch;
}
.menu a {
color: black;
}
.header-banner {
background: orange;
}
.header{
.header {
position: sticky;
top: 0;
left:0;
left: 0;
}
.footer {
position: sticky;
bottom: 0;
left:0;
.header-top {
align-self: stretch;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-element, .footer-element {
margin: 5px;
.header-top::after {
content: "";
}
.header-top img {
max-height: 2.5rem;
max-width: 10rem;
}
.header-element, .menu-item {
padding: var(--default-padding);
cursor: pointer;
}
.header-element {
color: black;
}
.menu-item {
background-color: #80808000;
transition: background-color 0.25s ease-in-out;
-webkit-transition: background-color 0.25s ease-in-out;
-moz-transition: background-color 0.25s ease-in-out;
-ms-transition: background-color 0.25s ease-in-out;
-o-transition: background-color 0.25s ease-in-out;
}
.menu-item:hover {
background-color: #80808080;
}
.inline {
display: inline-block;
}
@ -47,11 +133,17 @@ body {
}
body main {
margin: 10px;
margin: calc(2 * var(--default-padding));
}
.header-main {
flex-grow:1;
flex-grow: 1;
}
/* Gradient background, but only on the overview page (and when choosing expired entries to delete) */
.header-main:has(.joboffer-index) {
background: linear-gradient(45deg, var(--blue) 0%, var(--yellow) 100%);
background-size: cover;
}
.centered {
@ -74,16 +166,17 @@ body main {
.login-form {
display: grid;
grid-gap: 5px;
grid-template: [retry-msg] "m m"
[username] "ul ui"
[password] "pl pi"
[submit] "sb empty";
padding: 5px;
grid-gap: var(--default-padding);
grid-template: [retry-msg] "m m"[username] "ul ui"[password] "pl pi"[submit] "sb empty";
padding: var(--default-padding);
border-style: solid;
border-color: gray;
border-radius: 20px;
border-width: 2px;
border-color: var(--blue);
border-width: var(--default-padding);
border-radius: var(--default-padding);
-webkit-border-radius: var(--default-padding);
-moz-border-radius: var(--default-padding);
-ms-border-radius: var(--default-padding);
-o-border-radius: var(--default-padding);
}
@ -116,18 +209,18 @@ body main {
.submission-form {
display: grid;
grid-gap: 5px;
grid-template: [title] "tt tf"
[submitter] "st sf"
[contact] "ct cf"
[contact-public] "pt pc"
[expiry] "et es"
[attachments] "at at"
[links] "ln ln"
[notes] "nt nt"
[advanced] "ao ao"
[submit] "sb sb"
[footnote] "fn fn";
padding: 5px;
grid-template: [title] "tt tf"
[submitter] "st sf"
[contact] "ct cf"
[contact-public] "pt pc"
[expiry] "et es"
[attachments] "at at"
[links] "ln ln"
[notes] "nt nt"
[advanced] "ao ao"
[submit] "sb sb"
[footnote] "fn fn";
padding: var(--default-padding);
}
.advanced-options {
@ -211,39 +304,53 @@ body main {
display: flex;
flex-wrap: wrap;
justify-content: center;
grid-gap: 5px;
grid-gap: var(--default-padding);
}
.joboffer-index-entry {
width: 25em;
margin: 5px;
padding: 5px;
width: 25rem;
margin: var(--default-padding);
padding: var(--default-padding);
border-style: solid;
border-color: gray;
border-radius: 20px;
border-width: 2px;
border-color: var(--green);
border-width: var(--default-padding);
border-radius: var(--default-padding);
-webkit-border-radius: var(--default-padding);
-moz-border-radius: var(--default-padding);
-ms-border-radius: var(--default-padding);
-o-border-radius: var(--default-padding);
background-color: white;
}
.joboffer-index-entry.AwaitingReview, .joboffer-index-entry.UnPublished {
background: pink;
background: var(--light-yellow);
border-style: dashed;
border-color: var(--yellow);
}
.joboffer-index-entry:target {
background: LemonChiffon;
background: var(--light-green);
border-color: var(--dark-green);
}
.column, .submission-preview {
flex-direction:column
flex-direction: column;
gap: var(--default-padding);
}
.link-button {
margin: 5px;
margin: var(--default-padding);
border: solid;
border-radius: 10px;
border-color: black;
color: black;
padding: 5px;
color: white;
padding: var(--default-padding);
text-decoration: none;
background-color: var(--dark-blue);
border-color: var(--blue);
border-radius: var(--default-padding);
-webkit-border-radius: var(--default-padding);
-moz-border-radius: var(--default-padding);
-ms-border-radius: var(--default-padding);
-o-border-radius: var(--default-padding);
}
.expired, .unconfirmed, .unreviewed {
@ -262,36 +369,50 @@ body main {
display: inline-block;
}
.modal-confirm-box {
.modal-confirm-box {
display: inline-block;
border-style: solid;
border-radius: 5px;
border-color: var(--dark-blue);
border-radius: var(--default-padding);
-webkit-border-radius: var(--default-padding);
-moz-border-radius: var(--default-padding);
-ms-border-radius: var(--default-padding);
-o-border-radius: var(--default-padding);
}
input.modal-open-check:not(:checked) + .modal-confirm-box {
border-color: transparent;
input.modal-open-check:not(:checked)+.modal-confirm-box {
border-color: transparent;
}
.modal-confirm-box > .modal-open-button.confirm {
background-color: lightgreen;
border-radius: 5px;
padding: 5px;
.modal-confirm-box>.modal-open-button.confirm {
background-color: var(--green);
padding: var(--default-padding);
border-radius: var(--default-padding);
-webkit-border-radius: var(--default-padding);
-moz-border-radius: var(--default-padding);
-ms-border-radius: var(--default-padding);
-o-border-radius: var(--default-padding);
}
.modal-confirm-box > .modal-open-button.retract {
background-color: tomato;
border-radius: 5px;
padding: 5px;
.modal-confirm-box>.modal-open-button.retract {
background-color: var(--yellow);
padding: var(--default-padding);
border-radius: var(--default-padding);
-webkit-border-radius: var(--default-padding);
-moz-border-radius: var(--default-padding);
-ms-border-radius: var(--default-padding);
-o-border-radius: var(--default-padding);
}
input.modal-open-check:checked + .modal-confirm-box > .modal-open-button {
input.modal-open-check:checked+.modal-confirm-box>.modal-open-button {
display: none;
}
input.modal-open-check:not(:checked) + .modal-confirm-box > .modal-cancel-button {
input.modal-open-check:not(:checked)+.modal-confirm-box>.modal-cancel-button {
display: none;
}
input.modal-open-check:not(:checked) + .modal-confirm-box > .modal-submit-button {
input.modal-open-check:not(:checked)+.modal-confirm-box>.modal-submit-button {
visibility: hidden;
}
@ -307,14 +428,15 @@ input.modal-open-check:not(:checked) + .modal-confirm-box > .modal-submit-button
display: none;
}
.hideable-toggle:checked ~ label.hideable-label::after {
.hideable-toggle:checked~label.hideable-label::after {
content: "Show";
}
.hideable-toggle:not(:checked) ~ label.hideable-label::after {
.hideable-toggle:not(:checked)~label.hideable-label::after {
content: "Hide";
}
:checked.hideable-toggle ~ .hideable-target {
:checked.hideable-toggle~.hideable-target {
display: none;
}
@ -323,28 +445,29 @@ input.modal-open-check:not(:checked) + .modal-confirm-box > .modal-submit-button
display: flex;
align-items: center;
position: sticky;
background: var(--filter-bar-color);
top: 120px;
top: 8rem;
box-sizing: border-box;
left:0;
margin-bottom: 5px;
padding: 5px;
width: 100%;
box-shadow: 0px 0px 10px 0px gray;
left: 0;
background: white;
margin-bottom: var(--default-padding);
padding: var(--default-padding);
border: var(--default-padding) solid var(--blue);
width: fit-content;
}
.joboffer-filters > .filter-label[for="awaiting-review"] {
.joboffer-filters>.filter-label[for="awaiting-review"] {
margin-left: var(--default-padding);
border: solid;
padding: 5px;
border-color: gray;
padding: var(--default-padding);
border-color: var(--yellow);
border-radius: 20px;
border-width: 2px;
border-width: var(--default-padding);
}
#awaiting-review:checked ~ .joboffer-filters > .filter-label[for="awaiting-review"] {
background: cyan;
#awaiting-review:checked~.joboffer-filters>.filter-label[for="awaiting-review"] {
background: var(--light-yellow);
}
#awaiting-review:checked ~ .joboffer-index > .joboffer-index-entry:not(.AwaitingReview) {
#awaiting-review:checked~.joboffer-index>.joboffer-index-entry:not(.AwaitingReview) {
display: none;
}
}

View file

@ -3,12 +3,12 @@
<form class="login-form" method="post">
{{# if is_retry }}
<div class="message">Username or Password incorrect! </div>
<div class="message">Username or Password incorrect!</div>
{{/if}}
<label class="username-label" for="login-username">Username</label> <input id="login-username" class="username-input" type="text" name="username" autocomplete="username" required>
<label class="password-label" for="login-password">Password</label> <input id="login-password" class="password-input" type="password" name="password" autocomplete="current-password" required><br />
<button class="submit-button" type="submit">Login</button>
<label class="username-label" for="login-username">Benutzername</label> <input id="login-username" class="username-input" type="text" name="username" autocomplete="username" required>
<label class="password-label" for="login-password">Passwort</label> <input id="login-password" class="password-input" type="password" name="password" autocomplete="current-password" required><br />
<button class="submit-button" type="submit">Anmelden</button>
</form>
</div>
{{/base}}

View file

@ -14,6 +14,5 @@
{{> @partial-block }}
</main>
</div>
{{> footer}}
</body>
</html>

View file

@ -2,7 +2,7 @@
<input id="{{> kind}}-{{> id}}" class="hidden modal-open-check" type="checkbox" name="pre-{{> kind}}" required>
<div class="modal-confirm-box">
<label for="{{> kind}}-{{> id}}" class="modal-open-button {{> kind}}">{{> action}}</label>
<label for="{{> kind}}-{{> id}}" class="modal-cancel-button {{> kind}}">Cancel</label>
<button type="submit" class="modal-submit-button">Confirm {{> action}}</button>
<label for="{{> kind}}-{{> id}}" class="modal-cancel-button {{> kind}}">Abbrechen</label>
<button type="submit" class="modal-submit-button">{{> action}} bestätigen</button>
</div>
</form>

View file

@ -1,15 +1,18 @@
Moin,
Guten Tag,
Es wurde eine Stellenausschreibung mit dieser E-Mail Address als Kontakt-Address in unserer Jobbörse eingereicht.
es wurde eine Stellenausschreibung mit dieser E-Mail Addresse als Kontakt-Addresse auf unserer Jobbörse eingereicht.
Bitte überprüfen Sie die Stellenausschreibung unter dem folgenden Link.
Bitte überprüfen Sie die Stellenausschreibung unter folgendem Link:
{{{confirmation_link}}}
Dort können sie die Stellenausschreibung bestätigen oder zurückziehen.
Sie können Ihre Stellenausschreibung dort bestätigen oder zurückziehen.
Nach der Bestätigung kann der Link genutzt werden um die Stellenausschreibung vor Ablauf der Gültigkeit zu löschen.
Außerdem kann der Link nach der Bestätigung genutzt werden, um die Stellenausschreibung vor Ablauf ihrer Gültigkeit zu löschen.
Freundliche Grüße
Mit freundlichen Grüßen
Das Team der gemeinsamen Jobbörse der Fachschaften Informatik und Mathematik der CAU Kiel
Das Team der FS-InfMath Jobbörse
---
Diese Nachricht wurde automatisch erstellt.

View file

@ -1,9 +1,12 @@
Moin,
Guten Tag,
Es wurde eine Stellenausschreibung mit dieser E-Mail Address als Kontakt-Address in unserer Jobbörse veröffentlicht.
es wurde eine Stellenausschreibung mit dieser E-Mail Addresse als Kontakt-Addresse auf unserer Jobbörse veröffentlicht.
{{{highlight_link}}}
Freundliche Grüße
Mit freundlichen Grüßen
Das Team der gemeinsamen Jobbörse der Fachschaften Informatik und Mathematik der CAU Kiel
Das Team der FS-InfMath Jobbörse
---
Diese Nachricht wurde automatisch erstellt.

View file

@ -1,3 +1,3 @@
Automatischer Hinweis: Eine neue Stellenausschreibung wurde zur Jobbörse eingereicht!
Automatischer Hinweis: Auf der Jobbörse wurde eine neue Stellenanzeige eingereicht!
{{{highlight_link}}}

View file

@ -1,11 +1,11 @@
{{#> base}}
<div class="centered">
<div>
Die Aktion konnte nicht durchgeführt werden. <br />
Die Aktion konnte nicht durchgeführt werden.<br />
{{#if msg}}
{{msg}}
{{else}}
Es scheint ein un-kategorisiertes Problem mit ihrer Anfrage zu bestehen.
Es scheint ein nicht kategorisiertes Problem mit Ihrer Anfrage zu bestehen.
{{/if}}
</div>
</div>

View file

@ -1,8 +1,8 @@
{{#> base}}
<div class="centered">
<div>
Die Aktion konnte nicht durchgeführt werden. <br />
Authentifizierung notwendig, bitte loggen sie sich ein.
Die Aktion konnte nicht durchgeführt werden.<br />
Authentifizierung notwendig, bitte loggen Sie sich ein.
</div>
</div>
{{/base}}

View file

@ -1,7 +1,7 @@
{{#> base}}
<div class="centered">
<div>
Die von ihnen Angeforderte Resource scheint nicht zu existieren!
Die von Ihnen angeforderte Ressource scheint nicht zu existieren!
</div>
</div>
{{/base}}

View file

@ -1,9 +1,9 @@
{{#> base}}
<div class="centered">
<div>
Die Aktion konnte nicht durchgeführt werden. <br />
Es wurden zu viele Anfragen in zu kurzer Zeit gestellt. <br />
Bitte warten etwas bevor sie weitere Anfragen stellen.
Die Aktion konnte nicht durchgeführt werden.<br />
Es wurden zu viele Anfragen in zu kurzer Zeit gestellt.<br />
Bitte warten Sie etwas, bevor Sie weitere Anfragen stellen.
</div>
</div>
{{/base}}

View file

@ -1,8 +1,8 @@
{{#> base}}
<div class="centered">
<div>
Ein interner Fehler ist bei der bearbeitung ihrer Anfrage aufgetreten, bitte versuchen sie es erneut!<br />
Sollte der Fehler weiterhin bestehen, wenden sie sich bitte an einen Administrator!
Bei der Bearbeitung Ihrer Anfrage ist ein Fehler aufgetreten, bitte versuchen Sie es erneut!<br />
Sollte der Fehler weiterhin bestehen, wenden Sie sich bitte an einen Administrator!
</div>
</div>
{{/base}}

View file

@ -1,26 +0,0 @@
<footer class="footer">
<nav class="footer-inner">
{{#each base.links as |link|}}
{{#unless @first}}<span>|</span>{{/unless}}<a class="footer-element" href="{{link.url}}"><h3 class="inline">{{link.title}}</h3></a>
{{/each}}
<span>|</span><a class="footer-element" href="{{base.routes.licenses}}"><h3 class="inline">Third-party Licenses</h3></a>
<span>|</span><a class="footer-element" href="{{base.routes.joboffer_create}}"><h3 class="inline">Stellenanzeige Einreichen</h3></a>
{{#if user}}
<span>|</span><a class="footer-element" href="{{base.routes.joboffers_delete_expired}}" title="Delete all expired Job Offers"><h3 class="inline">Delete Expired</h3></a>
<span>|</span><label class="footer-element" for="submit-sync" tabindex="0">
<h3 class="inline" title="Reload Joboffer Metadata from Disk">Re-Sync</h3>
<form class="hidden" method="post" action="{{base.routes.sync}}">
<input type="submit" id="submit-sync" class="hidden">
</form>
</label>
<span>|</span><label class="footer-element" for="submit-logout" tabindex="0">
<h3 class="inline">Logout</h3>
<form class="hidden" method="post" action="{{base.routes.logout}}">
<input type="submit" id="submit-logout" class="hidden">
</form>
</label
{{else}}
<span>|</span><a class="footer-element" href="{{base.routes.login}}"><h3 class="inline">Reviewer Login</h3></a>
{{/if}}
</nav>
</footer>

View file

@ -11,6 +11,15 @@
{{/if}}
<header class="header">
<nav class="header-inner">
<a class="header-element" href="{{base.routes.joboffer_overview}}"><h1>Jobbörse</h1></a>
<div class="header-top">
<a class="header-element" href="https://www.fs-infmath.uni-kiel.de/wiki/Hauptseite">
<img src="https://www.fs-infmath.uni-kiel.de/w/images/9/9f/Logo_gro%C3%9F_bunt_kiel.svg">
</a>
<a class="header-element" href="{{base.routes.index}}">
<h1>Jobbörse</h1>
</a>
</div>
{{> menu}}
</nav>
<div class="header-bottom"></div>
</header>

View file

@ -1,26 +1,27 @@
{{#> base}}
<div class="centered submission-preview">
<div>
Stellenausschreibung erfolgreich übermittelt. <br />
Die Stellenausschreibung hat die ID {{job_offer.id}} erhalten. <br />
Stellenausschreibung erfolgreich übermittelt.<br />
Die Stellenausschreibung hat die ID {{job_offer.id}} erhalten.<br />
{{#unless job_offer.confirmed}}
{{#if email }}
Eine E-Mail mit einem Bestätigungslink wurde an die angegebene Kontakt-Adresse versand. <br />
Eine E-Mail mit einem Bestätigungslink wurde an die angegebene Kontakt-Adresse gesendet.<br />
{{else}}
Die Stellenausschreibung muss noch bestätigt werden, aber der Versand von Bestätigungsmails ist derzeit nicht möglich. <br />
Die Stellenausschreibung muss noch bestätigt werden, aber der Versand von Bestätigungsmails ist derzeit nicht möglich.<br />
Wir entschuldigen uns für etwaige Unannehmlichkeiten, die dadurch entstehen.
{{/if}}
{{# if job_offer.reviewed }}
Da ein Review bereits erfolgt ist, wird die Stellenausschreibung mit erfolgter Bestätigung veröffentlicht. <br />
Da ein Review bereits erfolgt ist, wird die Stellenausschreibung mit erfolgter Bestätigung veröffentlicht.<br />
{{else}}
Die Stellenausschreibung wurde zum Review eingereiht. <br />
Sobald Review und Bestätigung erfolgt sind wird die Stellenausschreibung veröffentlicht. <br />
Die Stellenausschreibung wurde zum Review eingereicht.<br />
Sobald Review und Bestätigung erfolgt sind, wird die Stellenausschreibung veröffentlicht.<br />
{{/if}}
{{else}}
{{#unless job_offer.reviewed}}
Die Stellenausschreibung wurde zum Review eingereiht. <br />
Sobald ein Review erfolgt ist wird die Stellenausschreibung veröffentlicht. <br />
Die Stellenausschreibung wurde zum Review eingereicht.<br />
Sobald ein Review erfolgt ist, wird die Stellenausschreibung veröffentlicht.<br />
{{else}}
Die Stellenausschreibung wurde veröffentlicht!
{{/unless}}

View file

@ -1,19 +1,19 @@
{{#> base}}
<div class="centered">
<form class="submission-form" method="post" enctype="multipart/form-data">
<label class="offer-title-title" for="offer-title">Title</label>
<label class="offer-title-title" for="offer-title">Titel der Anzeige</label>
<input class="offer-title-field" id="offer-title" type="text" name="title" autocomplete="on" autofocus placeholder="z.B. HiWi-Gesucht" required><br />
<label class="submitter-title" for="offer-offering-party">Anbieter</label>
<label class="submitter-title" for="offer-offering-party">Anbieter/Unternehmen</label>
<input class="submitter-field" id="offer-offering-party" type="text" name="offering_party" autocomplete="organization" placeholder="z.B. Weihnachtsmann & Co.KG. oder Institut für Informatik der CAU Kiel" required><br />
<label class="contact-title" for="contact-data">Kontakt E-Mail Address<sup>1</sup></label>
<label class="contact-title" for="contact-data">Kontakt-E-Mail-Addresse<sup>1</sup></label>
<input class="contact-field" id="contact-data" type="email" autocomplete="email" name="offer-contact" placeholder="max.mustermann@example.com" required>
<label class="publish-contact-title" for="publish-contact-data">Kontakt Adresse Öffentlich</label>
<label class="publish-contact-title" for="publish-contact-data">E-Mail-Adresse veröffentlichen</label>
<input class="publish-contact-checkbox" id="publish-contact-data" type="checkbox" name="offer-contact-visible" value="visible"><br />
<label class="expiry-title" for="offer-expiry">Gültig bis (Wenn nicht angegeben, 6 Monate nach Einsendung)</label>
<label class="expiry-title" for="offer-expiry">Gültig bis (wenn nicht angegeben, 6 Monate nach Einsendung)</label>
<input class="expiry-select" id="offer-expiry" type="date" name="offer_expiry" min="{{base.date}}"><br />
<fieldset class="attachment-area">
@ -23,7 +23,7 @@
<hr />
{{/unless}}
<div>
<input type="text" autocomplete="on" name="file_title[]" placeholder="Title"/>
<input type="text" autocomplete="on" name="file_title[]" placeholder="Anzeigename"/>
<input type="file" accept=".pdf" name="file[]"/>
<div/>
{{/each}}
@ -36,7 +36,7 @@
<hr />
{{/unless}}
<div>
<input type="text" autocomplete="on" name="link_title[]" placeholder="Online-Stellenausschreibung" />
<input type="text" autocomplete="on" name="link_title[]" placeholder="z.B. Online-Stellenausschreibung" />
<input type="url" autocomplete="url" name="link_url[]" pattern="https://.+" placeholder="{{@root.base.routes.index}}" />
<div/>
{{/each}}
@ -47,20 +47,20 @@
</div>
<div class="footnotes">
1: Die Kontakt Address wird für eine Bestätigungsmail und eventuelle Rückfragen benötigt, sie kann optional auch öffentlich als Teil des Stellenausschreibungseintrags angezeigt werden.<br />
2: Link URLs müssen mit "https://" beginnen
1: Die Kontakt-Addresse wird für eine Bestätigungsmail und eventuelle Rückfragen benötigt, sie kann optional auch öffentlich als Teil der Stellenausschreibung angezeigt werden.<br />
2: Link-URLs müssen mit "https://" beginnen
</div>
{{#if user }}
<fieldset class="advanced-options">
<legend>Erweiterte Optionen für Reviewer</legend>
<label class="backdate-title" for="offer-backdate">Eingegangen (Optionale Rückdatierung)</label>
<label class="backdate-title" for="offer-backdate">Eingangsdatum (optionale Rückdatierung)</label>
<input class="backdate-select" id="offer-backdate" type="datetime-local" name="backdate"><br />
<label class="review-title" for="approval"checked>Als bereits ge-reviwed markieren</label>
<label class="review-title" for="approval"checked>Als bereits ge-reviewed markieren</label>
<input id="approval" class="review-checkbox" type="checkbox" name="pre_approved" value="approved" checked><br />
<label class="review-title" for="confirmation">Überspringe die Bestätigung für diese Stellenausschreibung</label>
<label class="review-title" for="confirmation">Bestätigungsmail für diese Anzeige überspringen</label>
<input id="confirmation" class="confirmation-checkbox" type="checkbox" name="skip_confirmation" value="skip" checked><br />
<label class="infinite-title" for="permanent">Permanente Stellenausschreibung</label>
@ -68,7 +68,7 @@
</fieldset>
{{/if}}
<button class="submit-button" type="submit">Submit</button>
<button class="submit-button" type="submit">Stellenausschreibung einreichen</button>
</form>
</div>
{{/base}}

View file

@ -7,13 +7,13 @@
{{> job_offer/overview-entry job_offer=job_offer base=../base user=../user}}
</label>
{{else}}
There are no expired job offers to delete!
Es gibt keine zu löschenden Stellenanzeigen!
{{/each}}
</div>
{{#if expired_job_offers }}
<input type="hidden" name="only_expired" value="true">
<hr />
<button type="submit">Delete selected Job Offers</button>
<button type="submit">Ausgewählte Stellenanzeigen löschen</button>
{{/if}}
</form>
{{/base}}

View file

@ -3,19 +3,19 @@
<form class="submission-form" method="post" enctype="multipart/form-data">
<input type="hidden" name="hash" value="{{job_offer.hash}}" />
<label class="offer-title-title" for="offer-title">Title</label>
<label class="offer-title-title" for="offer-title">Titel der Anzeige</label>
<input class="offer-title-field" id="offer-title" type="text" name="title" autocomplete="on" autofocus value="{{job_offer.title}}" required><br />
<label class="submitter-title" for="offer-offering-party">Anbieter</label>
<label class="submitter-title" for="offer-offering-party">Anbieter/Unternehmen</label>
<input class="submitter-field" id="offer-offering-party" type="text" name="offering_party" autocomplete="organization" value="{{job_offer.offering_party}}" required><br />
<label class="contact-title" for="contact-data">Kontakt E-Mail Address<sup>1</sup></label>
<label class="contact-title" for="contact-data">Kontakt-E-Mail-Addresse<sup>1</sup></label>
<input class="contact-field" id="contact-data" type="email" autocomplete="email" name="offer-contact" value="{{job_offer.contact_data}}" required>
<label class="publish-contact-title" for="publish-contact-data">Kontakt Adresse Öffentlich</label>
<label class="publish-contact-title" for="publish-contact-data">E-Mail-Adresse öffentlich</label>
<input class="publish-contact-checkbox" id="publish-contact-data" type="checkbox" name="offer-contact-visible" value="visible" {{#if job_offer.public_contact_data}}checked="checked"{{/if}}><br />
<label class="expiry-title" for="offer-expiry">Gültig bis (Wenn nicht angegeben, 6 Monate nach Einsendung)</label>
<label class="expiry-title" for="offer-expiry">Gültig bis (wenn nicht angegeben, 6 Monate nach Einsendung)</label>
<input class="expiry-select" id="offer-expiry" type="date" name="offer_expiry" {{#if job_offer.expiry_date }}value="{{job_offer.expiry_date}}"{{/if}}><br />
<fieldset class="attachment-area">
@ -27,9 +27,9 @@
{{/unless}}
<input type="text" autocomplete="on" name="file_title_edit[]" value="{{attachment.title}}" />
<input type="text" name="file_name_edit[]" value="{{attachment.file_name}}" />
| <a href="{{attachment.attachment_location}}" target="_blank">View Attachment</a>
| <label for="delete-{{@index}}">Delete Attachment</label> <input id="delete-{{@index}}" type="checkbox" name="delete_attachment[]" value="{{@index}}" />
| <label for="replace-{{@index}}">Replace Attachment</label> <input id="replace-{{@index}}" type="file" accept=".pdf" name="file_replace[]" title="Replace Attachment" />
| <a href="{{attachment.attachment_location}}" target="_blank">Anhang öffnen</a>
| <label for="delete-{{@index}}">Anhang löschen</label> <input id="delete-{{@index}}" type="checkbox" name="delete_attachment[]" value="{{@index}}" />
| <label for="replace-{{@index}}">Anhang ersetzen</label> <input id="replace-{{@index}}" type="file" accept=".pdf" name="file_replace[]" title="Anhang ersetzen" />
<div/>
{{/each}}
{{#each form.remaining_attachments }}
@ -41,7 +41,7 @@
{{/if}}
{{/unless}}
<div>
<input type="text" autocomplete="on" name="file_title[]" placeholder="Title"/>
<input type="text" autocomplete="on" name="file_title[]" placeholder="Anzeigename"/>
<input type="file" accept=".pdf" name="file[]"/>
<div/>
{{/each}}
@ -65,14 +65,14 @@
</div>
<div class="footnotes">
1: Die Kontakt Address wird für eine Bestätigungsmail und eventuelle Rückfragen benötigt, sie kann optional auch öffentlich als Teil des Stellenausschreibungseintrags angezeigt werden.<br />
2: Link URLs müssen mit "https://" beginnen
1: Die Kontakt-Addresse wird für eine Bestätigungsmail und eventuelle Rückfragen benötigt, sie kann optional auch öffentlich als Teil der Stellenausschreibung angezeigt werden.<br />
2: Link-URLs müssen mit "https://" beginnen
</div>
{{#if user }}
<fieldset class="advanced-options">
<legend>Erweiterte Optionen für Reviewer</legend>
<label class="backdate-title" for="offer-backdate">Eingegangen (Optionales Umdatieren)</label>
<label class="backdate-title" for="offer-backdate">Eingangsdatum (optionales Umdatieren)</label>
<input class="backdate-select" id="offer-backdate" type="datetime-local" name="backdate"><br />
<label class="infinite-title" for="permanent">Permanente Stellenausschreibung</label>
@ -80,7 +80,7 @@
</fieldset>
{{/if}}
<button class="submit-button" type="submit">Submit</button>
<button class="submit-button" type="submit">Stellenausschreibung aktualisieren</button>
</form>
</div>
{{/base}}

View file

@ -1,19 +1,22 @@
{{#> base}}
<h1>FAQ</h1>
<div>
<h2>Was ist zu beachten?</h2>
<p>Die Jobbörse wird durch einen Teil der freiwilligen aktiven Mitglieder der Fachschaften betreut,
dies kann vor allem außerhalb der Vorlesungszeit und im Prüfungszeitraum zu längeren bearbeitungszeiten bei E-mail-Einreichungen und Reviews führen.</p>
dies kann vor allem außerhalb der Vorlesungszeit und während der Prüfungszeiträume zu längeren Bearbeitungszeiten bei E-Mail-Einreichungen und Reviews führen.</p>
<p>Die Aktuellen Semester- und Prüfungszeiträume sollten sich <a href="https://www.uni-kiel.de/gf-praesidium/de/termine/semesterzeiten">hier</a> finden.</p>
<p>Die Aktuellen Semester- und Prüfungszeiträume sollten Sie <a href="https://www.uni-kiel.de/gf-praesidium/de/termine/semesterzeiten">hier</a> finden.</p>
<p class="italic-text">Bei technischen Problemen oder wenn Sie das Formular nicht nutzen können bzw. dürfen, senden Sie bitte eine E-Mail an <a href="{{mail}}">{{mail}}</a>. Wir helfen Ihnen gerne!</p>
</div>
<div>
<h2>Laufzeit</h2>
<p>Einreichungen werden automatisch entfernt sobald das jeweilige Ablaufdatum verstrichen ist</p>
<p>Einreichungen werden automatisch entfernt, sobald das jeweilige Ablaufdatum verstrichen ist</p>
<p>Einreichungen ohne explizit angegebenes Ablaufdatum haben ein implizites Ablaufdatum 6 Monate (180 Tage) nach Einreichung.</p>
{{#if mail}}
<p>Um eine Einreichung früher zu entfernen informieren sie uns bitte per E-Mail unter <a href="{{mail}}">{{mail}}</a></p>
<p>Um eine Einreichung früher zu entfernen, informieren Sie uns bitte per E-Mail unter <a href="{{mail}}">{{mail}}</a>.</p>
{{/if}}
</div>
@ -24,20 +27,20 @@
<div>
<h2>Wie kann eine Einreichung erfolgen?</h2>
<p>Der bevorzugte Weg für Einreichungen ist das <a href="{{base.routes.joboffer_create}}" >Web-Formular</a>.<p/>
<p>Eine zügige bearbeitung von Einreichungen per E-Mail kann nicht garantiert werden,
insbesondere außerhalb des Vorlesungszeitraums und im Prüfungszeitraum.</p>
<p>Der bevorzugte Weg für Einreichungen ist das <a href="{{base.routes.joboffer_create}}">Web-Formular</a>.<p/>
<p>Eine zügige Bearbeitung von Einreichungen per E-Mail kann nicht garantiert werden,
insbesondere außerhalb des Vorlesungszeitraums und während der Prüfungszeiträume.</p>
</div>
{{#if mail}}
<div>
<h2>Ich habe keine Bestätigungsmail erhalten!</h2>
Die Bestätigungsmail werden automatisch und unverzüglich versand sobald das Web-Formular erfolgreich auf dem Server eingegangen ist und die Einreichung gespeichert wurde.<br />
Daraufhin sollten sie zu einer ersten Vorschau der eingereichten Stellenausschreibung gebracht worden sein, mit entsprechendem Text darüber das eine Bestätigungsmail versand wurde.<br />
Diese sollten innerhalb weniger Minuten bei ihnen eingehen, meist jedoch schneller.
Die Bestätigungsmails werden automatisch und unverzüglich gesendet, sobald das Web-Formular erfolgreich auf dem Server eingegangen ist und die Einreichung gespeichert wurde.<br />
Daraufhin sollten Sie zu einer ersten Vorschau der eingereichten Stellenausschreibung gebracht worden sein, mit entsprechendem Text darüber, dass eine Bestätigungsmail versandt wurde.<br />
Diese sollten innerhalb weniger Minuten bei Ihnen eingehen, meist jedoch schneller.
Sollten sie nicht Zeitnah eine Bestätigungsmail erhalten,
schauen sie bitte erst in ihren Spam/Junk-Ordner und wenden sie sich dann an <a href="{{mail}}">{{mail}}</a>.
Sollten Sie nicht zeitnah eine Bestätigungsmail erhalten,
schauen sie bitte erst in ihren Spam/Junk-Ordner und wenden Sie sich dann ggf. an <a href="{{mail}}">{{mail}}</a>.
</div>
{{/if}}
@ -46,7 +49,21 @@
Dies kann primär zwei Gründe haben:
<ol>
<li>Sie haben zwar den Link geöffnet, aber unter der Vorschau nicht auf bestätigen/veröffentlichen geklickt.</li>
<li>Es ist unsererseits noch kein review der Einreichung erfolgt.</li>
<li>Es ist unsererseits noch kein Review der Einreichung erfolgt.</li>
</ol>
</div>
<div>
<h2>Werden die Stellenausschreibungen vor Ort ausgehangen?</h2>
Nein, die Fachschaft verfügt aktuell nicht über ein analoges „Schwarzes Brett“
und kann Stellenanzeigen somit auch nicht aushängen.
</div>
<div>
<h2>Andere Job-Portale</h2>
Falls Sie noch weitere Job-Portale suchen, auf denen Sie Ihre Stellenausschreibungen schalten können,
finden Sie auch in unserem
<a href="https://www.fs-infmath.uni-kiel.de/wiki/Frequently_Asked_Questions#Jobs" target"_blank">FAQ für Internationale Studierende</a>
eine Liste von Job-Portalen.
</div>
{{/base}}

View file

@ -22,14 +22,14 @@
{{# if job_offer.contact_data }}
<br />
Kontakt Adresse: <a href="mailto:{{job_offer.contact_data}}">{{job_offer.contact_data}}</a>
Kontakt-Adresse: <a href="mailto:{{job_offer.contact_data}}">{{job_offer.contact_data}}</a>
{{/if}}
{{#if job_offer.attachments }}
{{#each job_offer.attachments as |attachment| }}
{{# if @first}}
<hr />
<h3> Anhänge </h3>
<h3>Anhänge</h3>
<ul>
{{/if}}
<li>
@ -46,7 +46,7 @@
{{#each job_offer.links as |link| }}
{{# if @first}}
<hr />
<h3> Links </h3>
<h3>Links</h3>
<ul>
{{/if}}
<li>
@ -68,10 +68,10 @@
{{#if job_offer.actions.highlight_link }}
<div>ID: <a href="{{job_offer.actions.highlight_link}}" >{{job_offer.id}}</a></div>
{{/if}}
<div>Review Status: <span class="{{#unless job_offer.reviewed}}unreviewed{{/unless}}">{{job_offer.status.review_status}}</span></div>
<div>Confirmation Status: <span class="{{#unless job_offer.confirmed}}unconfirmed{{/unless}}">{{job_offer.status.confirmation_status.type}}</span></div>
<div>Review-Status: <span class="{{#unless job_offer.reviewed}}unreviewed{{/unless}}">{{job_offer.status.review_status}}</span></div>
<div>Bestätigungsstatus: <span class="{{#unless job_offer.confirmed}}unconfirmed{{/unless}}">{{job_offer.status.confirmation_status.type}}</span></div>
{{#if job_offer.actions.confirmation_link}}
<div><a href="mailto:{{job_offer.contact_data}}?body=Confirmation%20Link:%20{{job_offer.actions.confirmation_link}}" >Manual Confirmation Mail</a></div>
<div><a href="mailto:{{job_offer.contact_data}}?body=Confirmation%20Link:%20{{job_offer.actions.confirmation_link}}" >Manuelle Bestätigungsmail senden</a></div>
{{/if}}
{{/unless}}
@ -82,7 +82,7 @@
{{#> confirm-modal}}
{{#*inline "id"}}{{job_offer.id}}{{/inline}}
{{#*inline "kind"}}unpublish{{/inline}}
{{#*inline "action"}}{{#if job_offer.published}}Un-Publish{{else}}Retract Review{{/if}}{{/inline}}
{{#*inline "action"}}{{#if job_offer.published}}Veröffentlichung zurückziehen{{else}}Review zurückziehen{{/if}}{{/inline}}
{{#*inline "formaction"}}{{job_offer.actions.unpublish_url}}{{/inline}}
{{/confirm-modal}}
{{/if}}
@ -91,7 +91,7 @@
{{#> confirm-modal}}
{{#*inline "id"}}{{job_offer.id}}{{/inline}}
{{#*inline "kind"}}publish{{/inline}}
{{#*inline "action"}}{{#if job_offer.confirmed}}Publish{{else}}Review{{/if}}{{/inline}}
{{#*inline "action"}}{{#if job_offer.confirmed}}Veröffentlichen{{else}}Als gereviewed markieren{{/if}}{{/inline}}
{{#*inline "formaction"}}{{job_offer.actions.publish_url}}{{/inline}}
{{/confirm-modal}}
{{/if}}
@ -101,7 +101,7 @@
{{#> confirm-modal}}
{{#*inline "id"}}{{job_offer.id}}{{/inline}}
{{#*inline "kind"}}delete{{/inline}}
{{#*inline "action"}}Delete{{/inline}}
{{#*inline "action"}}Löschen{{/inline}}
{{#*inline "formaction"}}{{job_offer.actions.delete_url}}{{/inline}}
{{/confirm-modal}}
{{/if}}

View file

@ -1,13 +1,13 @@
{{#> base}}
{{#if user}}
<input id="awaiting-review" class="hidden" type="checkbox">
<div class="joboffer-filters .shadow"><span class="bold-text">Filter:</span> <label class="filter-label" for="awaiting-review">Awaiting Review</label></div>
<div class="joboffer-filters .shadow"><span class="bold-text">Filter:</span> <label class="filter-label" for="awaiting-review">Noch nicht gereviewed</label></div>
{{/if}}
<div class="joboffer-index">
{{#each job_offers as |job_offer|}}
{{> job_offer/overview-entry job_offer=job_offer base=../base user=../user}}
{{else}}
There are currently no published job offers!
Aktuell gibt es keine veröffentlichten Stellenanzeigen!
{{/each}}
</div>
{{/base}}

View file

@ -1,11 +1,11 @@
{{#> base}}
<div class="centered column">
<div>
Die Stellenausschreibung wurde erfolgreich bestätigt! <br />
Die Stellenausschreibung wurde erfolgreich bestätigt!<br />
{{# if is_awaiting_review}}
Sobald ein Review erfolgt ist wird die Stellenausschreibung veröffentlicht! <br />
Sobald ein Review erfolgt ist, wird die Stellenausschreibung veröffentlicht!<br />
{{else}}
Da ein Review bereits erfolgt ist, wird sie damit ab sofort veröffentlicht! <br />
Da ein Review bereits erfolgt ist, ist die Stellenausschreibung ab sofort in der Übersicht!<br />
{{/if}}
<br />
<nav>

View file

@ -1,7 +1,7 @@
{{#> base}}
<div class="centered column">
<div>
Die Stellenausschreibung wurde erfolgreich gelöscht! <br />
Die Stellenausschreibung wurde erfolgreich gelöscht!<br />
<br />
<nav>
<a class="link-button" href="{{base.routes.joboffer_overview}}">Zur Übersicht der Stellenausschreibungen</a>

View file

@ -0,0 +1,33 @@
<nav class="menu">
{{#each base.links as |link|}}
<a class="menu-item" href="{{link.url}}">
<h3 class="inline">{{link.title}}</h3>
</a>
{{/each}}
<a class="menu-item" href="{{base.routes.licenses}}">
<h3 class="inline">Drittanbieter-Lizenzen</h3>
</a>
<a class="menu-item" href="{{base.routes.joboffer_create}}">
<h3 class="inline">Stellenanzeige einreichen</h3>
</a>
{{#if user}}
<a class="menu-item" href="{{base.routes.joboffers_delete_expired}}"
title="Alle abgelaufenen Stellenanzeigen löschen">
<h3 class="inline">Abgelaufene löschen</h3>
</a>
<label class="menu-item" for="submit-sync" tabindex="0">
<h3 class="inline" title="Reload Joboffer Metadata from Disk">Re-Sync</h3>
<form class="hidden" method="post" action="{{base.routes.sync}}">
<input type="submit" id="submit-sync" class="hidden">
</form>
</label>
<label class="menu-item" for="submit-logout" tabindex="0">
<h3 class="inline">Abmelden</h3>
<form class="hidden" method="post" action="{{base.routes.logout}}">
<input type="submit" id="submit-logout" class="hidden">
</form>
</label {{else}} <a class="menu-item" href="{{base.routes.login}}">
<h3 class="inline">Fachschaftler-Login</h3>
</a>
{{/if}}
</nav>

View file

@ -0,0 +1,3 @@
Stellenausschreibung veröffentlicht:
[**{{{title}}}**]({{{link}}})
*{{{company}}}*