Compare commits

...

37 Commits

Author SHA1 Message Date
f9fe47a414 feat(shop/build): Updates shop js, also removes minify process 2020-01-23 11:39:56 +01:00
beff5209f8 fix(issue20): Keeps only the 1st paragraph on job text (homepage) 2020-01-23 11:39:04 +01:00
5b50aa01c1 fix(issue20): Corrects job text, updates on homepage/jobpage 2020-01-23 11:25:21 +01:00
2002f4b913 fix(mobile/menu): Removes topnav effect 2020-01-23 11:10:54 +01:00
58214dc179 fix(issue20): Corrects typo and puts line in italic 2020-01-23 11:06:56 +01:00
d7e40e0e3d fix(issue20): Updates first image 2020-01-23 11:06:23 +01:00
9b4bb0fd7c fix(issue11): Removess useless info rule message 2020-01-22 19:06:56 +01:00
12650be390 feat(issue20): Adds info job in home page 2020-01-22 18:55:17 +01:00
bc7adaf32f feat(issue20): Customizes job page 2020-01-22 18:16:32 +01:00
be9848097e fix(issue17): Improves dynamic changes to fixed height 2020-01-22 16:48:00 +01:00
16ebbfa683 Merge branch 'master' of https://git.m-labs.hk/M-Labs/web2019 2020-01-22 16:21:50 +01:00
c9eb9376b3 fix(issue17): Sets fixed height 2020-01-22 16:20:58 +01:00
5f42340b04 fix(menu/scroll): Allows effect only on mobile 2020-01-22 16:10:41 +01:00
0191350c48 fix(mobile/shop): Corrects height of dark right side when menu is opened 2020-01-22 15:59:25 +01:00
9d03f68ec6 feat(mobile/shop): Adds feedback when add new card from backlog 2020-01-22 15:47:10 +01:00
a27c7370d6 fix(mobile/menu): Shows when scroll top 2020-01-21 12:24:57 +01:00
72ce996c37 fix(mobile/shop): Tries to improvie menu show/hide while scrolling 2020-01-21 12:02:38 +01:00
d08bfbdcc0 revert(mobile/shop): Hides menu when scroll down and shows when scroll up 2020-01-20 18:02:47 +01:00
e96c0dc524 fix(mobile/shop): Removes btn delete card from crate
because no mouseover on mobile
2020-01-20 17:43:33 +01:00
14ec597b85 fix(mobile/menu): Hides menu when scroll down and shows when scroll up 2020-01-20 17:07:53 +01:00
b3076efb2b fix(mobile/shop): Corrects card hidden while dragging outside backlog 2020-01-20 11:29:51 +01:00
0987164982 fix(mobile/shop): Adds zindex to main while menu open 2020-01-19 15:19:48 +01:00
31105263b5 fix(mobile/shop): Adds zindex to cloned card while dragging 2020-01-19 15:15:51 +01:00
5b95796160 fix(mobile/shop): Corrects drag/drop because of transform3d 2020-01-19 15:07:41 +01:00
952eccd560 feat(mobile/landscape): Makes disappear the header menu 2020-01-15 12:06:18 +01:00
475eb92d82 fix(mobile/landscape/lowres): Hides aside menu 2020-01-15 10:40:53 +01:00
4ebe4f253c fix(mobile): Reduces size of menu sub-items 2020-01-02 14:44:21 +01:00
1ac9fdd641 fix(mobile): Reduces sizes a bit of other elements 2019-12-30 11:48:42 +01:00
489326dc47 fix(mobile): Reduces header menu height 2019-12-30 11:34:18 +01:00
faeaf48d9d feat(mobile): Adds mobile landscape 2019-12-30 11:14:04 +01:00
efd6b92298 fix(mobile): Corrects various things in style 2019-12-26 15:30:09 +01:00
31fabb7cbd fix(mobile): Updates bug styles for tablet 2019-12-26 15:19:10 +01:00
230f78f338 fix(mobile): Increases space between row in table summary price 2019-12-26 15:11:54 +01:00
393eeafbd6 fix(mobile): Updates width table summary price 2019-12-26 15:01:49 +01:00
7a4cc84a56 fix(mobile): Uses flex for table 2019-12-26 14:57:38 +01:00
804e5fb712 fix(mobile): Removes default button style for side menu 2019-12-26 14:51:55 +01:00
a4c77f3872 feat(mobile): Adapts design for mobile/tablet 2019-12-26 14:31:37 +01:00
28 changed files with 2699 additions and 63 deletions

View File

@ -1,13 +1,33 @@
+++
title = "Jobs"
weight = 1
template = "page.html"
template = "page-custom-footer-design.html"
+++
{% layout_centered_content() %}
##### We are looking for talented people to join our team.
{% end %}
{% layout_centered_content(force_left=true, min_width=true) %}
We are looking for talented people to join our team. If you want to be at the intersection of physics and engineering, collaborate with world-class scientists, and have the freedom to work with cutting-edge open source technology such as embedded Rust, LLVM, and next-generation FPGA tools such as the nMigen language and Yosys - then consider a job at M-Labs.
{% layout_centered_content(min_width=true) %}
If you want to be at the intersection of physics and engineering, collaborate with world-class scientists, and have the freedom to work with cutting-edge open source technology such as embedded Rust, LLVM, and next-generation FPGA tools such as the nMigen language and Yosys - then consider a job at M-Labs.
{% end %}
{{ layout_photo_style_1(src1="images/IMG_20170818_175543_HDR@2x.png", src2="images/IMG_0027-side@2x.png") }}
{% layout_centered_content(min_width=true) %}
<i>The laboratories at NIST and PTB, where some of the main ARTIQ installations are located</i>
{% end %}
{{ layout_photo_style_1(src1="images/IMG_0591-side@2x.png", src2="images/IMG_0591@2x.png") }}
{% layout_centered_content(min_width=true) %}
Our office is located in the center of Hong Kong, a cosmopolitan city with world-class infrastructure, many cultural and social events, and <a href="https://www.discoverhongkong.com/eng/see-do/great-outdoors/hikes/index.jsp" rel="noopener noreferrer" target="_blank">beautiful natural scenery</a>. It has a separate system from mainland China, where, for example, communications are unrestricted, taxes are low, and customs tariffs virtually inexistent. Hong Kong is located next to Shenzhen, a city with <a href="https://www.wired.co.uk/video/shenzhen-full-documentary" rel="noopener noreferrer" target="_blank">a bustling tech scene</a>, and where many of the world's electronic gadgets are designed and manufactured.
@ -15,6 +35,9 @@ For local applicants, now is your chance to work on top-notch science and techno
We also accept remote positions, and you may also choose to work at our sister company QUARTIQ GmbH in Berlin-Adlershof, Germany.
Contact us at jobs@m-****.hk!
{% end %}
{% layout_centered_content() %}
##### Contact us at jobs@m-****.hk!
{% end %}

View File

@ -10,33 +10,33 @@ template = "page.html"
<div class="row">
{% layout_card(title="ARTIQ manual") %}
{% layout_card(title="ARTIQ manual", sameheight=100) %}
<small>Stable version</small>
<a href="https://m-labs.hk/artiq/manual.pdf" target="_blank">PDF</a> | <a href="https://m-labs.hk/artiq/manual/" target="_blank" rel="noopener noreferrer">HTML</a>
{% end %}
{% layout_card(title="SiPyCo manual") %}
{% layout_card(title="SiPyCo manual", sameheight=100) %}
<small>Starting with ARTIQ-5, this library replaces <tt>artiq.protocols</tt>.</small>
<a href="https://m-labs.hk/artiq/sipyco-manual.pdf" target="_blank">PDF</a> | <a href="https://m-labs.hk/artiq/sipyco-manual/" target="_blank" rel="noopener noreferrer">HTML</a>
{% end %}
{% layout_card(title="ARTIQ manual") %}
{% layout_card(title="ARTIQ manual", sameheight=100) %}
<small>Beta (development) version</small>
<a href="https://m-labs.hk/artiq/manual-beta.pdf" target="_blank">PDF</a> | <a href="https://m-labs.hk/artiq/manual-beta/" target="_blank" rel="noopener noreferrer">HTML</a>
{% end %}
{% layout_card(title="Slideshow") %}
{% layout_card(title="Slideshow", sameheight=100) %}
<small>The ARTIQ experiment control system</small>
<a href="/docs/artiq/artiq_overview.pdf" target="_blank" rel="noopener noreferrer">View slides</a>
{% end %}
{% layout_card(title="Slideshow") %}
{% layout_card(title="Slideshow", sameheight=100) %}
<small>Timing control in ARTIQ</small>
<a href="/docs/artiq/slides_timing.pdf" target="_blank" rel="noopener noreferrer">View slides</a>
@ -120,51 +120,51 @@ We welcome inquiries from research groups of all sizes.<br><a href="https://gith
<div class="row">
{% layout_card(title="Entangler core") %}
{% layout_card(title="Entangler core", sameheight=120) %}
<small>A FPGA core written in Migen with ARTIQ interface, for controlling remote quantum entanglement of trapped ions.</small>
<a href="https://github.com/OxfordIonTrapGroup/entangler-core" target="_blank" rel="noopener noreferrer">Repository</a> | <a href="https://arxiv.org/abs/1911.10841" target="_blank" rel="noopener noreferrer">Paper</a>
{% end %}
{% layout_card(title="ndscan") %}
{% layout_card(title="ndscan", sameheight=120) %}
<small>N-dimensional scans for ARTIQ</small>
<a href="https://github.com/OxfordIonTrapGroup/ndscan" target="_blank" rel="noopener noreferrer">Repository</a>
{% end %}
{% layout_card(title="Oxford routines") %}
{% layout_card(title="Oxford routines", sameheight=120) %}
<small>Oxford Ion-Trap Group routines</small>
<a href="https://github.com/OxfordIonTrapGroup/oitg" target="_blank" rel="noopener noreferrer">Repository</a>
{% end %}
{% layout_card(title="Terminal interface") %}
{% layout_card(title="Terminal interface", sameheight=120) %}
<small>A terminal interface for the Advanced Real-Time Infrastructure for Quantum physics (ARTIQ).</small>
<a href="https://github.com/chase1635321/ARTIQ" target="_blank" rel="noopener noreferrer">Repository</a>
{% end %}
{% layout_card(title="ARTIQ-suservo") %}
{% layout_card(title="ARTIQ-suservo", sameheight=120) %}
<small>A set of scripts for the ARTIQ suservo device.</small>
<a href="https://github.com/chase1635321/ARTIQ-suservo" target="_blank" rel="noopener noreferrer">Repository</a>
{% end %}
{% layout_card(title="nvOS") %}
{% layout_card(title="nvOS", sameheight=120) %}
<small>A quantum operating system built around ARTIQ and NV centers in diamond.</small>
<a href="https://github.com/vontell/nvOS" target="_blank" rel="noopener noreferrer">Repository</a>
{% end %}
{% layout_card(title="Haeffner Lab routines") %}
{% layout_card(title="Haeffner Lab routines", sameheight=120) %}
<small>Haeffner Lab (Berkeley) routines</small>
<a href="https://github.com/HaeffnerLab/artiq-work-lattice" target="_blank" rel="noopener noreferrer">Repository</a>
{% end %}
{% layout_card(title="WIPM routines") %}
{% layout_card(title="WIPM routines", sameheight=120) %}
<small>WIPM (CAS Wuhan) routines</small>
<a href="https://github.com/GuanQunMu/IonTrap-WIPM" target="_blank" rel="noopener noreferrer">Repository</a>

View File

@ -21,8 +21,7 @@
"babel": {
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"minify"
"@babel/preset-react"
]
}
}

View File

@ -113,7 +113,6 @@ img.kf25 {
width: 310px;
}
// Small devices (landscape phones, 576px and up)
@media (min-width: 576px) {
@ -217,7 +216,7 @@ img.kf25 {
}
.card-jobs {
background: #fff url("../images/jobs@2x.png") no-repeat center right;
background: #fff url("../images/jobs-min@2x.png") no-repeat top right;
}
.logos-centered {
@ -240,4 +239,15 @@ img.kf25 {
// Extra large devices (large desktops, 1200px and up)
@media (min-width: 1200px) {
}
/*
##Device = Low Resolution Tablets, Mobiles (Landscape)
##Screen = B/w 481px to 767px
*/
@media (min-width: 481px) and (max-width: 767px) {
#root-shop, #root-shop>div {
height: 100%;
}
}

View File

@ -0,0 +1,562 @@
.mobileCloseMenu {
display: flex;
justify-content: flex-end;
padding: 1em 1em 0;
}
.simu-clone {
z-index: 10;
}
.feedback-add-success {
display: none;
}
/*
##Device = Tablets, Ipads (portrait)
##Screen = B/w 768px to 1024px
*/
@media (min-width: 768px) and (max-width: 1080px) {
.logo > img {
height: 20px;
}
.navbar {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
body {
font-size: .7rem;
}
#root-shop, #root-shop>div {
height: calc(100vh - 50px);
}
#root-shop .productItem {
padding: 2rem 1rem 1rem;
}
#root-shop .productItem .content img {
height: 300px;
}
#root-shop .productItem .content .price {
padding: .5rem;
}
#root-shop .productItem .content h3 {
font-size: 1.5rem;
}
#root-shop .productItem .content ul {
font-size: .6rem;
}
#root-shop .panel .control {
flex-direction: column;
margin-bottom: 1.5rem;
}
#root-shop .panel .control > .description,
#root-shop .panel .control > .crate-mode {
width: 100%;
}
#root-shop .panel .control > .crate-mode {
text-align: left;
}
#root-shop .panel .summary {
flex-direction: column;
}
#root-shop .panel .summary>.summary-price table {
font-size: 1rem;
}
#root-shop .panel .summary>.summary-form form {
width: 100%;
}
#root-shop .panel {
padding: 1.5rem;
}
#root-shop .mobileBtnDisplaySideMenu,
#root-shop .mobileCloseMenu {
display: none !important;
}
#root-shop .mobileBtnDisplaySideMenu button,
#root-shop .mobileCloseMenu button {
-webkit-appearance: none !important;
background: none !important;
border: none !important;
}
#root-shop table {
width: 100%;
max-width: 100%;
}
#root-shop table tr {
padding: .8em 0;
display: flex !important;
justify-content: space-between;
}
}
/*
##Device = Tablets, Ipads (landscape)
##Screen = B/w 768px to 1024px
*/
@media (min-width: 768px) and (max-width: 1080px) and (orientation: landscape) {
.logo > img {
height: 20px;
}
.navbar {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
body {
font-size: .7rem;
}
#root-shop, #root-shop>div {
height: calc(100vh - 50px);
}
#root-shop .mobileBtnDisplaySideMenu,
#root-shop .mobileCloseMenu {
display: none !important;
}
#root-shop .mobileBtnDisplaySideMenu button,
#root-shop .mobileCloseMenu button {
-webkit-appearance: none !important;
background: none !important;
border: none !important;
}
#root-shop table {
width: 100%;
max-width: 100%;
}
#root-shop table tr {
padding: .8em 0;
display: flex !important;
justify-content: space-between;
}
#root-shop .panel .summary {
flex-direction: column;
}
#root-shop .panel .summary>.summary-price table {
font-size: .7rem;
}
#root-shop .panel .summary>.summary-form form {
width: 100%;
}
#root-shop .panel .summary>.summary-price tfoot {
font-size: .85rem;
}
#root-shop .panel .summary>.summary-form form input[type="submit"] {
margin-bottom: 1em;
}
}
/*
##Device = Low Resolution Tablets, Mobiles (Landscape)
##Screen = B/w 481px to 767px
*/
@media (min-width: 481px) and (max-width: 767px) {
.feedback-add-success {
background-color: green;
display: block;
position: fixed;
top: 20px;
right: 20px;
padding: 1em;
z-index: 100000;
color: white;
border-radius: 10px;
box-shadow: 0 0 5px 3px;
}
.dropdown-item {
font-size: .75em;
}
/*.sticky-top {
position: fixed;
}*/
.logo > img {
height: 20px;
}
.navbar {
padding-top: 5px;
padding-bottom: 5px;
}
body {
font-size: .7rem;
}
#root-shop, #root-shop>div {
/*height: calc(100vh - 50px);*/
height: 100%;
}
#root-shop .productItem {
padding: 1rem .5rem .5rem;
}
#root-shop .productItem .content img {
height: 230px;
}
#root-shop .productItem .content .price {
padding: .3rem;
}
#root-shop .productItem .content h3 {
font-size: 1rem;
}
#root-shop .productItem .content ul {
font-size: .5rem;
}
#root-shop .panel {
padding: 1.3rem;
}
#root-shop .panel .control {
flex-direction: column;
margin-bottom: 1.5rem;
}
#root-shop .panel .control > .description,
#root-shop .panel .control > .crate-mode {
width: 100%;
}
#root-shop .panel .control > .crate-mode {
text-align: left;
}
#root-shop .panel .summary {
flex-direction: column;
}
#root-shop .panel h2 {
font-size: 1.5rem;
}
#root-shop .panel .summary>.summary-price table {
font-size: .7rem;
}
#root-shop .panel .summary>.summary-form form {
width: 100%;
}
#root-shop .panel .summary>.summary-price tfoot {
font-size: .85rem;
}
#root-shop .panel .summary>.summary-form form input[type="submit"] {
margin-bottom: 1em;
}
#root-shop .mobileBtnDisplaySideMenu {
background-color: #0d3547;
border-bottom-right-radius: 30px;
border-top-right-radius: 30px;
width: 80px;
padding: 5px 0 5px 10px;
margin-bottom: -25px;
margin-left: -1.3rem;
position: relative;
z-index: 1;
}
#root-shop .mobileBtnDisplaySideMenu button,
#root-shop .mobileCloseMenu button {
-webkit-appearance: none;
background: none;
border: none;
}
#root-shop table {
width: 100%;
max-width: 100%;
}
#root-shop table tr {
padding: .8em 0;
display: flex !important;
justify-content: space-between;
}
#root-shop .layout>aside.aside.menu-opened {
/*transform: translate3d(0, 0, 0);*/
transition: left .3s;
width: 310px;
left: 0;
}
#root-shop .layout>aside.aside.menu-opened + section.main {
/*transform: translate3d(310px, 0, 0);*/
transition: left .3s;
left: 310px;
position: relative;
z-index: 0;
}
#root-shop .layout>aside.aside.menu-opened + section.main:after {
content: '';
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .3);
top: 0;
bottom: 0;
z-index: 10;
}
#root-shop .layout>aside.aside {
/*transform: translate3d(-310px, 0px, 0px);*/
transition: left .3s;
position: fixed;
z-index: 1;
left: -310px;
width: 310px;
height: 100%;
}
#root-shop .layout>aside.aside:after {
width: 0;
}
#root-shop .layout>aside.aside + section.main {
/*transform: translate3d(0, 0, 0);*/
transition: left .3s;
left: 0;
}
#root-shop .layout>section.main {
flex: 1;
max-width: 100%;
}
.should-disappear {
display: none!important;
}
#root-shop .layout>aside.aside.menu-opened {
overflow: initial;
}
#root-shop .layout>aside.aside.menu-opened > .backlog-container {
overflow-y: scroll;
height: 100%;
}
}
/*
##Device = Most of the Smartphones Mobiles (Portrait)
##Screen = B/w 320px to 479px
*/
@media (min-width: 320px) and (max-width: 480px) {
.feedback-add-success {
background-color: green;
display: block;
position: fixed;
top: 20px;
right: 20px;
padding: 1em;
z-index: 100000;
color: white;
border-radius: 10px;
box-shadow: 0 0 5px 3px;
}
.dropdown-item {
font-size: .75em;
}
/*.sticky-top {
position: fixed;
}*/
.logo > img {
height: 20px;
}
.navbar {
padding-top: 5px;
padding-bottom: 5px;
}
body {
font-size: .7rem;
}
#root-shop, #root-shop>div {
height: calc(100vh - 50px);
}
#root-shop .productItem {
padding: 1rem .5rem .5rem;
}
#root-shop .productItem .content .price {
padding: .3rem;
}
#root-shop .productItem .content h3 {
font-size: 1rem;
}
#root-shop .layout>aside.aside.menu-opened {
/*transform: translate3d(0, 0, 0);*/
transition: left .3s;
width: 310px;
left: 0;
}
#root-shop .layout>aside.aside.menu-opened + section.main {
/*transform: translate3d(310px, 0, 0);*/
transition: left .3s;
left: 310px;
position: relative;
z-index: 0;
}
#root-shop .layout>aside.aside.menu-opened + section.main:after {
content: '';
position: fixed;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .3);
top: 0;
bottom: 0;
}
#root-shop .layout>aside.aside {
/*transform: translate3d(-310px, 0px, 0px);*/
transition: left .3s;
position: fixed;
z-index: 1;
left: -310px;
width: 310px;
height: 100%;
}
#root-shop .layout>aside.aside:after {
width: 0;
}
#root-shop .layout>aside.aside + section.main {
/*transform: translate3d(0, 0, 0);*/
transition: left .3s;
left: 0;
}
#root-shop .layout>section.main {
flex: 1;
max-width: 100%;
}
#root-shop .productItem {
padding: 2rem 1rem 1rem;
}
#root-shop .productItem .content img {
height: 300px;
}
#root-shop .productItem .content .price {
padding: .5rem;
}
#root-shop .panel {
padding: 1.3rem;
}
#root-shop .panel .control {
flex-direction: column;
margin-bottom: 1.5rem;
}
#root-shop .panel h2 {
font-size: 1.5rem;
}
#root-shop .panel .control > .description,
#root-shop .panel .control > .crate-mode {
width: 100%;
}
#root-shop .panel .control > .crate-mode {
text-align: left;
}
#root-shop .panel .summary {
flex-direction: column;
}
#root-shop .panel .summary>.summary-price table {
font-size: .7rem;
}
#root-shop .panel .summary>.summary-form form {
width: 100%;
}
#root-shop .panel .summary>.summary-price tfoot {
font-size: .85rem;
}
#root-shop .panel .summary>.summary-form form input[type="submit"] {
margin-bottom: 1em;
}
#root-shop .mobileBtnDisplaySideMenu {
background-color: #0d3547;
border-bottom-right-radius: 30px;
border-top-right-radius: 30px;
width: 80px;
padding: 5px 0 5px 10px;
margin-bottom: 15px;
margin-left: -1.3rem;
}
#root-shop .mobileBtnDisplaySideMenu button,
#root-shop .mobileCloseMenu button {
-webkit-appearance: none;
background: none;
border: none;
}
#root-shop table {
width: 100%;
max-width: 100%;
}
#root-shop table tr {
padding: .8em 0;
display: flex !important;
justify-content: space-between;
}
#root-shop .layout>aside.aside.menu-opened {
overflow: initial;
}
#root-shop .layout>aside.aside.menu-opened > .backlog-container {
overflow-y: scroll;
height: 100%;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 KiB

BIN
static/images/IMG_0027.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 KiB

BIN
static/images/IMG_0591.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

BIN
static/images/jobs-min.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22">
<g id="Group_441" data-name="Group 441" transform="translate(-1251 -346)">
<rect id="Rectangle_1020" data-name="Rectangle 1020" width="22" height="22" transform="translate(1251 346)" fill="none"/>
<rect id="Rectangle_1021" data-name="Rectangle 1021" width="2.4" height="24" transform="translate(1269.778 347.808) rotate(45)" fill="#fff"/>
<rect id="Rectangle_1022" data-name="Rectangle 1022" width="2.4" height="24" transform="translate(1271.192 364.778) rotate(135)" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 594 B

2
static/js/jquery-3.3.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -136,6 +136,16 @@ class Layout extends React.PureComponent {
return {
aside: PropTypes.any,
main: PropTypes.any,
mobileSideMenuShouldOpen: PropTypes.bool,
isMobile: PropTypes.bool,
newCardJustAdded: PropTypes.bool,
onClickToggleMobileSideMenu: PropTypes.func,
};
}
static get defaultProps() {
return {
mobileSideMenuShouldOpen: false,
};
}
@ -143,14 +153,28 @@ class Layout extends React.PureComponent {
const {
aside,
main,
mobileSideMenuShouldOpen,
isMobile,
newCardJustAdded,
onClickToggleMobileSideMenu
} = this.props;
return (
<div className="layout">
<aside className="aside">{aside}</aside>
<aside className={'aside ' + (mobileSideMenuShouldOpen ? 'menu-opened' : '')}>{aside}</aside>
<section className="main">{main}</section>
{mobileSideMenuShouldOpen ? (
<section className="main" onClick={onClickToggleMobileSideMenu}>{main}</section>
) : (
<section className="main">{main}</section>
)}
{isMobile && newCardJustAdded ? (
<div className="feedback-add-success">
added
</div>
) : null}
</div>
);
@ -182,9 +206,9 @@ class ProductItem extends React.PureComponent {
this.handleOnClickAddItem = this.handleOnClickAddItem.bind(this);
}
handleOnClickAddItem(index, e) {
handleOnClickAddItem(index, tap, e) {
if (this.props.onClickAddItem) {
this.props.onClickAddItem(index);
this.props.onClickAddItem(index, tap);
}
e.preventDefault();
}
@ -221,7 +245,7 @@ class ProductItem extends React.PureComponent {
<div className="content">
<button onClick={this.handleOnClickAddItem.bind(this, index)}>
<button onClick={this.handleOnClickAddItem.bind(this, index, true)}>
<img src="/images/shop/icon-add.svg" alt="add" />
</button>
@ -241,7 +265,7 @@ class ProductItem extends React.PureComponent {
{/* Allows to simulate a clone */}
{snapshot.isDragging && (
<img className="" src={image} />
<img className="simclone" src={image} />
)}
</React.Fragment>
)}
@ -263,6 +287,7 @@ class ProductCartItem extends React.PureComponent {
static get propTypes() {
return {
isMobile: PropTypes.bool,
hovered: PropTypes.bool,
index: PropTypes.number.isRequired,
model: PropTypes.object.isRequired,
@ -326,14 +351,14 @@ class ProductCartItem extends React.PureComponent {
}
handleOnMouseEnterRemoveItem(index, e) {
if (this.props.onToggleOverlayRemove) {
if (this.props.onToggleOverlayRemove && !this.props.isMobile) {
this.props.onToggleOverlayRemove(index, true);
}
e.preventDefault();
}
handleOnMouseLeaveRemoveItem(index, e) {
if (this.props.onToggleOverlayRemove) {
if (this.props.onToggleOverlayRemove && !this.props.isMobile) {
this.props.onToggleOverlayRemove(index, false);
}
e.preventDefault();
@ -543,6 +568,7 @@ class Cart extends React.PureComponent {
static get propTypes() {
return {
isMobile: PropTypes.bool,
nbrSlots: PropTypes.number,
itemHovered: PropTypes.string,
data: PropTypes.object.isRequired,
@ -555,6 +581,7 @@ class Cart extends React.PureComponent {
render() {
const {
isMobile,
nbrSlots,
itemHovered,
data,
@ -571,6 +598,7 @@ class Cart extends React.PureComponent {
}
return (
<ProductCartItem
isMobile={isMobile}
hovered={item.id === itemHovered}
key={item.id}
index={index}
@ -722,6 +750,8 @@ class OrderPanel extends React.PureComponent {
crate: PropTypes.element,
summaryPrice: PropTypes.element,
form: PropTypes.element,
isMobile: PropTypes.bool,
onClickToggleMobileSideMenu: PropTypes.func,
};
}
@ -733,6 +763,8 @@ class OrderPanel extends React.PureComponent {
crate,
summaryPrice,
form,
isMobile,
onClickToggleMobileSideMenu
} = this.props;
return (
@ -746,6 +778,14 @@ class OrderPanel extends React.PureComponent {
{crateMode}
</div>
{isMobile ? (
<div className="mobileBtnDisplaySideMenu">
<button onClick={onClickToggleMobileSideMenu}>
<img src="/images/shop/icon-add.svg" alt="add" />
</button>
</div>
) : null}
{crate}
<section className="summary">
@ -1026,7 +1066,9 @@ class Backlog extends React.PureComponent {
currency: PropTypes.string,
data: PropTypes.object.isRequired,
items: PropTypes.object,
isMobile: PropTypes.bool,
onClickAddItem: PropTypes.func,
onClickToggleMobileSideMenu: PropTypes.func,
};
}
@ -1042,6 +1084,8 @@ class Backlog extends React.PureComponent {
data,
items,
onClickAddItem,
onClickToggleMobileSideMenu,
isMobile,
} = this.props;
const ordered_items = data.itemIds.map(itemId => items[itemId]);
@ -1072,6 +1116,14 @@ class Backlog extends React.PureComponent {
ref={provided.innerRef}
{...provided.droppableProps}>
{isMobile ? (
<div className="mobileCloseMenu">
<button onClick={onClickToggleMobileSideMenu}>
<img src="/images/shop/icon-close-white.svg" alt="add" />
</button>
</div>
) : null}
{products}
{provided.placeholder && (
@ -1115,6 +1167,9 @@ class Shop extends React.PureComponent {
this.handleClickSelectItem = this.handleClickSelectItem.bind(this);
this.handleClickSubmit = this.handleClickSubmit.bind(this);
this.handleToggleOverlayRemove = this.handleToggleOverlayRemove.bind(this);
this.handleClickToggleMobileSideMenu = this.handleClickToggleMobileSideMenu.bind(this);
this.timer = null;
}
componentDidMount() {
@ -1152,6 +1207,18 @@ class Shop extends React.PureComponent {
prevState.columns.cart.items,
this.state.columns.cart.items);
}
if (this.state.newCardJustAdded) {
this.timer = setTimeout(() => {
this.setState({
newCardJustAdded: false,
});
}, 2000);
}
}
componentWillUnmount() {
clearTimeout(this.timer);
}
handleCrateModeChange(mode) {
@ -1202,7 +1269,7 @@ class Shop extends React.PureComponent {
});
}
handleClickAddItem(index) {
handleClickAddItem(index, tap) {
const source = {
droppableId: 'backlog',
index: index,
@ -1215,8 +1282,8 @@ class Shop extends React.PureComponent {
this.handleOnDragEnd({
source,
destination,
draggableId: null,
});
draggableId: null
}, tap);
}
handleToggleItemProgress(index, show) {
@ -1331,7 +1398,7 @@ class Shop extends React.PureComponent {
a.click();
}
handleOnDragEnd(result) {
handleOnDragEnd(result, newAdded) {
const {
source,
destination,
@ -1342,6 +1409,7 @@ class Shop extends React.PureComponent {
if (source.droppableId === 'cart') {
this.setState({
...this.state,
newCardJustAdded: false,
columns: {
...this.state.columns,
[source.droppableId]: {
@ -1363,6 +1431,7 @@ class Shop extends React.PureComponent {
case 'backlog':
this.setState({
...this.state,
newCardJustAdded: newAdded ? true : false,
columns: {
...this.state.columns,
[destination.droppableId]: {
@ -1382,6 +1451,7 @@ class Shop extends React.PureComponent {
case destination.droppableId:
this.setState({
...this.state,
newCardJustAdded: false,
columns: {
...this.state.columns,
[destination.droppableId]: {
@ -1401,6 +1471,13 @@ class Shop extends React.PureComponent {
}
}
handleClickToggleMobileSideMenu() {
this.setState({
...this.state,
mobileSideMenuShouldOpen: !this.state.mobileSideMenuShouldOpen,
});
}
checkAlerts(prevItems, newItems) {
console.log('--- START CHECKING CRATE WARNING ---');
@ -1485,7 +1562,9 @@ class Shop extends React.PureComponent {
}
if (nbUsedSlot > itemsCloned[idx].nbrSlotMax) {
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
if (itemsCloned[idx].rules.maxSlot.message) {
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
}
itemsData[idx].warnings.maxSlotWarning = {...itemsCloned[idx].rules.maxSlotWarning};
}
@ -1624,7 +1703,9 @@ class Shop extends React.PureComponent {
}
if (nbUsedSlot > 0) {
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
if (itemsCloned[idx].rules.maxSlot.message) {
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
}
}
if (nbUsedSlot > itemsCloned[idx].nbrSlotMax) {
itemsData[idx].warnings.maxSlotWarning = {...itemsCloned[idx].rules.maxSlotWarning};
@ -1684,23 +1765,35 @@ class Shop extends React.PureComponent {
items,
columns,
rules,
mobileSideMenuShouldOpen,
newCardJustAdded,
} = this.state;
const isMobile = window.deviceIsMobile();
return (
<DragDropContext onDragEnd={this.handleOnDragEnd}>
<Layout
className="shop"
mobileSideMenuShouldOpen={mobileSideMenuShouldOpen}
isMobile={isMobile}
newCardJustAdded={newCardJustAdded}
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
aside={
<Backlog
currency={currency}
items={items}
data={columns['backlog']}
onClickAddItem={this.handleClickAddItem}>
onClickAddItem={this.handleClickAddItem}
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
isMobile={isMobile}>
</Backlog>
}
main={(
<OrderPanel
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
isMobile={isMobile}
title="Order hardware"
description="
Drag and drop the cards you want into the crate below to see how the combination would look like. If you have any issues with this ordering system, or if you need other configurations, email us directly anytime at sales@m-****.hk. The price is estimated and must be confirmed by a quote."
@ -1716,6 +1809,7 @@ class Shop extends React.PureComponent {
<Cart
nbrSlots={crateModeSlots[currentMode]}
data={columns['cart']}
isMobile={isMobile}
itemHovered={currentItemHovered}
onToggleProgress={this.handleToggleItemProgress}
onToggleWarning={this.handleToggleItemWarning}

1895
static/js/shop.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,6 @@
const shop_data = {
mobileSideMenuShouldOpen: false,
currentItemHovered: null,
currentMode: 'rack',
currency: 'USD',
@ -358,7 +359,7 @@ const shop_data = {
type: 'hd68-max-slot',
icon: '/shop/icon-reminder.svg',
name: 'HD68-IDC',
message: 'HD68-IDC has at most 4 IDC-BNC adapters.',
message: null,
},
maxSlotWarning: {
type: 'hd68-max-slot-warning',

View File

@ -49,11 +49,11 @@
<!-- HEADER -->
<div class="container-fluid shadow th sticky-top">
<div class="container-fluid container-header shadow th sticky-top">
<header class="container">
<nav class="navbar navbar-expand-lg navbar-light bg-th-1 justify-content-center justify-content-between pt-3 pb-3" role="navigation">
<nav class="navbar navbar-expand-lg navbar-light bg-th-1 justify-content-center justify-content-between pt-md-3 pb-md-3" role="navigation">
<a class="navbar-brand logo mr-0" href="/">
<img src="{{ get_url(path='images/logo@2x.png') }}" height="25" alt="logo">
@ -83,9 +83,9 @@
<div class="dropdown-menu shadow-none shadow-lg text-left text-lg-left" aria-labelledby="navbarDropdown">
{% for tmp_page in subsection.pages %}
{% if tmp_page.extra.menu_item and tmp_page.extra.menu_item == "th1" %}
<a class="dropdown-item pt-2 pb-2 pt-sm-3 pb-sm-3 mx-4 mt-2 mb-2 mt-sm-3 mb-sm-3 w-auto btn btn-primary btn-inversed {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
<a class="dropdown-item pt-2 pb-2 mx-4 mt-2 mb-2 mt-sm-3 mb-sm-3 w-auto btn btn-primary btn-inversed {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
{% else %}
<a class="dropdown-item pt-2 pb-2 pt-sm-3 pb-sm-3 {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
<a class="dropdown-item pt-2 pb-2 {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
{% endif %}
{% endfor %}
</div>
@ -157,6 +157,9 @@
<small>Copyright &copy; <span id="copyright_year"></span>, M-Labs. All Rights Reserved.</small>
</p>
{% block fcopyright %}
{% endblock %}
</footer>
{% endblock footer %}
@ -179,7 +182,7 @@
<!-- <script src="{{ get_url(path='js/as.js', cachebust=true) }}"></script> -->
<script src="{{ get_url(path='js/jquery-3.3.1.slim.min.js', cachebust=true) }}"></script>
<script src="{{ get_url(path='js/jquery-3.3.1.min.js', cachebust=true) }}"></script>
<script src="{{ get_url(path='js/popper-1.14.7.min.js', cachebust=true) }}"></script>
<script src="{{ get_url(path='js/bootstrap-4.3.1.min.js', cachebust=true) }}"></script>

View File

@ -111,12 +111,8 @@
<p class="card-text pt-3">
We are looking for talented people to join our team. If you want to be at the intersection of physics and engineering, collaborate with world-class scientists, and have the freedom to work with cutting-edge open source technology such as embedded Rust, LLVM, and next-generation FPGA tools such as the nMigen language and Yosys - then consider a job at M-Labs.
</p>
<p class="card-text pt-3"><small>
Our office is located in the center of Hong Kong, a cosmopolitan city with world-class infrastructure, many cultural and social events, and <a href="https://www.discoverhongkong.com/eng/see-do/great-outdoors/hikes/index.jsp" rel="noopener noreferrer" target="_blank">beautiful natural scenery</a>. It has a separate system from mainland China, where, for example, communications are unrestricted, taxes are low, and customs tariffs virtually inexistent. Hong Kong is located next to Shenzhen, a city with <a href="https://www.wired.co.uk/video/shenzhen-full-documentary" rel="noopener noreferrer" target="_blank">a bustling tech scene</a>, and where many of the world's electronic gadgets are designed and manufactured.<br />
For local applicants, now is your chance to work on top-notch science and technology projects with partners worldwide, including Oxford University and <a href="https://www.nist.gov/nist-and-nobel/dave-wineland" rel="noopener noreferrer" target="_blank">NIST</a> - in <a href="https://web.archive.org/web/20170114210545/https://www.nature.com/articles/s41570-016-0001" rel="noopener noreferrer" target="_blank">a field whose applications are responsible for 20% of GDP</a>. For international applicants, Hong Kong provides <a href="https://www.immd.gov.hk/eng/services/visas/GEP.html" rel="noopener noreferrer" target="_blank">fast</a>, <a href="https://www.immd.gov.hk/eng/services/fee-tables/index.html" rel="noopener noreferrer" target="_blank">low-cost</a>, and relatively hassle-free employment visa processing.<br />
We also accept remote positions, and you may also choose to work at our sister company QUARTIQ GmbH in Berlin-Adlershof, Germany.<br />
Contact us at jobs@m-****.hk!
</small></p>
<a href="{{ get_url(path='@/about-us/jobs.md') }}" class="btn btn-primary btn-lg">Find out More</a>
</div>
@ -142,3 +138,22 @@
</main>
{% endblock %}
{% block fcopyright %}
<div class="container text-center">
<p class="pb-2 text-center">
<small><a href="https://commons.wikimedia.org/wiki/File:Intel_2nd_Generation_Core_microprocessor_codenamed_Sandy_Bridge_Wafer.jpg" target="_blank" rel="noopener noreferrer">Intel 2nd Generation Core microprocessor codenamed Sandy Bridge Wafer</a> by <a href="https://www.flickr.com/photos/intelfreepress/" target="_blank" rel="noopener noreferrer">Intel Free Press</a> is licensed under the <a href="https://creativecommons.org/licenses/by-sa/2.0/deed.en" target="_blank" rel="noopener noreferrer">CC BY-SA 2.0</a> license.</small>
<br />
<small><a href="https://commons.wikimedia.org/wiki/File:Hong_kong_bruce_lee_statue.jpg" target="_blank" rel="noopener noreferrer">Hong Kong Bruce Lee statue</a> by <a href="https://commons.wikimedia.org/w/index.php?+title=User%3AJohnson_Lau" target="_blank" rel="noopener noreferrer">Johnson Lau</a> is licensed under the <a href="https://creativecommons.org/licenses/by-sa/2.5/deed.en" target="_blank" rel="noopener noreferrer">CC BY-SA 2.5</a> license.</small>
</p>
</div>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends 'page.html' %}
{% block outside %}
<div class="container-fluid hero3 d-flex flex-column justify-content-center">
</div>
{% endblock %}

View File

@ -1,6 +1,12 @@
{% extends 'section.html' %}
{% block deferred_styles %}
{{ super() }}
<link rel="stylesheet" href="{{ get_url(path='css/order-hardware.css', cachebust=true) }}">
{% endblock %}
{% block hero %}{% endblock %}
@ -21,9 +27,22 @@
(function () {
function deviceIsMobile() {
// https://coderwall.com/p/i817wa/one-line-function-to-detect-mobile-devices-with-javascript
return (typeof window.orientation !== 'undefined') || (navigator.userAgent.indexOf('IEMobile') !== -1);
return (
(typeof window.orientation !== 'undefined') ||
navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPad/i) ||
navigator.userAgent.match(/iPod/i) ||
navigator.userAgent.match(/BlackBerry/i) ||
navigator.userAgent.match(/Windows Phone/i) ||
(navigator.userAgent.indexOf('IEMobile') !== -1)
);
};
window.deviceIsMobile = deviceIsMobile;
return;
if (deviceIsMobile()) {
alert('The online crate configuration tool is not available for mobile browsers yet. Please use a desktop computer or email us at sales@m-l****.hk to get a quote.');
}

View File

@ -17,7 +17,9 @@
</div>
{% endif %}
{{ body | markdown | safe }}
<div {% if sameheight %}style="height: {{ sameheight }}px"{% endif%}>
{{ body | markdown | safe }}
</div>
</div>

View File

@ -0,0 +1,19 @@
<div class="{% if css %}{{ css }}{% else %}row d-flex align-items-center mt-5 mb-5{% endif %}">
<div class="col-12 col-md-6 mb-3 mb-md-0">
{% if src1 %}
<img class="img-fluid" src="{{ get_url(path=src1) }}">
{% endif %}
</div>
<div class="col-12 col-md-6">
{% if src2 %}
<img class="img-fluid" src="{{ get_url(path=src2) }}">
{% endif %}
</div>
</div>