优化加入我们界面
更新了招新新闻 优化招生进度样式 优化录取进度查询
This commit is contained in:
+575
-39
@@ -13,6 +13,72 @@
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.join-submit-notice {
|
||||
margin: -6px 0 14px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid color-mix(in srgb, #2f82ff 42%, var(--border-default) 58%);
|
||||
border-left-width: 3px;
|
||||
border-radius: 4px;
|
||||
background: color-mix(in srgb, #2f82ff 10%, var(--bg-card) 90%);
|
||||
color: var(--text-primary);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.join-news-strip {
|
||||
margin-bottom: 20px;
|
||||
padding: 0 0 10px;
|
||||
}
|
||||
|
||||
.join-news-strip-track {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.join-news-item {
|
||||
--join-news-cols: 5;
|
||||
flex: 0 0 calc((100% - (var(--join-news-cols) - 1) * 14px) / var(--join-news-cols));
|
||||
width: calc((100% - (var(--join-news-cols) - 1) * 14px) / var(--join-news-cols));
|
||||
min-width: 0;
|
||||
padding-right: 12px;
|
||||
border-right: 1px solid color-mix(in srgb, var(--border-default) 82%, transparent);
|
||||
}
|
||||
|
||||
.join-news-item:last-child {
|
||||
border-right: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.join-news-item-title {
|
||||
margin: 0;
|
||||
font-size: 0.94rem;
|
||||
line-height: 1.38;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.join-news-item-title a {
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.join-news-item-title a:hover,
|
||||
.join-news-item-title a:focus-visible {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.join-news-item-excerpt {
|
||||
margin: 7px 0 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.join-news-strip-empty {
|
||||
margin: 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.join-hero {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -22,7 +88,7 @@
|
||||
|
||||
.join-canvas-shell {
|
||||
position: relative;
|
||||
border: 1px solid var(--border-default);
|
||||
height: clamp(280px, 31vw, 440px);
|
||||
border-radius: 18px;
|
||||
overflow: hidden;
|
||||
background: color-mix(in srgb, var(--bg-card) 94%, transparent);
|
||||
@@ -30,21 +96,25 @@
|
||||
}
|
||||
|
||||
.join-stage-photo-frame {
|
||||
position: relative;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.join-stage-photo {
|
||||
width: 100%;
|
||||
height: clamp(220px, 28vw, 360px);
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.join-wave-layer {
|
||||
position: relative;
|
||||
margin-top: clamp(-20px, -2.4vw, -12px);
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin-top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.join-progress-canvas {
|
||||
@@ -107,11 +177,18 @@
|
||||
}
|
||||
|
||||
.join-wave-mark.is-lighthouse {
|
||||
width: clamp(22px, 2vw, 30px);
|
||||
transform: translate(-50%, -80%);
|
||||
width: clamp(54px, 5.1vw, 81px);
|
||||
transform: translate(-50%, -82%);
|
||||
transform-origin: 50% 96%;
|
||||
}
|
||||
|
||||
.join-wave-mark.is-lighthouse.is-docked {
|
||||
top: auto;
|
||||
bottom: -1px;
|
||||
left: auto;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.join-wave-mark.is-active {
|
||||
filter: drop-shadow(0 0 10px color-mix(in srgb, var(--color-primary) 36%, transparent));
|
||||
}
|
||||
@@ -227,16 +304,105 @@
|
||||
.join-canvas-overlay {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
z-index: 2;
|
||||
max-width: 540px;
|
||||
padding: 14px 16px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid color-mix(in srgb, var(--border-default) 72%, transparent);
|
||||
background: color-mix(in srgb, var(--bg-body) 68%, transparent);
|
||||
backdrop-filter: blur(6px);
|
||||
-webkit-backdrop-filter: blur(6px);
|
||||
left: 0;
|
||||
right: auto;
|
||||
width: min(44vw, 360px);
|
||||
z-index: 3;
|
||||
isolation: isolate;
|
||||
overflow: hidden;
|
||||
max-width: 100%;
|
||||
padding: 12px 22px 12px 24px;
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
color-mix(in srgb, var(--bg-body) 78%, transparent) 0%,
|
||||
color-mix(in srgb, var(--bg-body) 78%, transparent) 34%,
|
||||
color-mix(in srgb, var(--bg-body) 48%, transparent) 50%,
|
||||
color-mix(in srgb, var(--bg-body) 16%, transparent) 64%,
|
||||
rgba(0, 0, 0, 0) 78%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.join-canvas-overlay.is-enter-animate {
|
||||
animation: join-overlay-slide-in 720ms cubic-bezier(0.2, 0.78, 0.18, 1) both;
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
|
||||
@keyframes join-overlay-slide-in {
|
||||
from {
|
||||
transform: translateX(-112%);
|
||||
opacity: 0.24;
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.join-canvas-overlay::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0.88;
|
||||
mix-blend-mode: soft-light;
|
||||
background:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 255, 255, 0.12) 0%,
|
||||
rgba(255, 255, 255, 0.06) 42%,
|
||||
rgba(255, 255, 255, 0.03) 60%,
|
||||
rgba(255, 255, 255, 0) 100%
|
||||
),
|
||||
repeating-linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.05) 0 1px,
|
||||
rgba(255, 255, 255, 0) 1px 3px
|
||||
),
|
||||
repeating-linear-gradient(
|
||||
45deg,
|
||||
rgba(0, 0, 0, 0.03) 0 1px,
|
||||
rgba(0, 0, 0, 0) 1px 4px
|
||||
);
|
||||
backdrop-filter: blur(9px) saturate(130%);
|
||||
-webkit-backdrop-filter: blur(9px) saturate(130%);
|
||||
-webkit-mask-image: linear-gradient(
|
||||
90deg,
|
||||
#000 0%,
|
||||
#000 56%,
|
||||
rgba(0, 0, 0, 0.6) 66%,
|
||||
rgba(0, 0, 0, 0) 78%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
mask-image: linear-gradient(
|
||||
90deg,
|
||||
#000 0%,
|
||||
#000 56%,
|
||||
rgba(0, 0, 0, 0.6) 66%,
|
||||
rgba(0, 0, 0, 0) 78%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-size: 100% 100%;
|
||||
}
|
||||
|
||||
.join-canvas-overlay > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.join-canvas-overlay.is-enter-animate {
|
||||
animation: none;
|
||||
transform: none;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.join-current-label {
|
||||
@@ -259,6 +425,14 @@
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.join-current-location {
|
||||
margin: 4px 0 0;
|
||||
font-size: 0.88rem;
|
||||
color: color-mix(in srgb, var(--text-primary) 84%, var(--text-secondary) 16%);
|
||||
line-height: 1.45;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.join-stage-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
@@ -269,22 +443,77 @@
|
||||
}
|
||||
|
||||
.join-stage-item {
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: 10px;
|
||||
background: color-mix(in srgb, var(--bg-card) 95%, transparent);
|
||||
padding: 10px 11px;
|
||||
position: relative;
|
||||
border: 1px solid color-mix(in srgb, var(--border-default) 90%, transparent);
|
||||
border-radius: 4px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
color-mix(in srgb, var(--bg-card) 90%, transparent) 0%,
|
||||
color-mix(in srgb, var(--bg-card) 97%, transparent) 100%
|
||||
);
|
||||
padding: 11px 12px;
|
||||
min-height: 98px;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.22s ease, background 0.22s ease, box-shadow 0.22s ease, transform 0.22s ease;
|
||||
}
|
||||
|
||||
.join-stage-item::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 2px;
|
||||
background: color-mix(in srgb, var(--border-default) 75%, transparent);
|
||||
opacity: 0.86;
|
||||
}
|
||||
|
||||
.join-stage-item.is-active,
|
||||
.join-stage-item.is-current {
|
||||
border-color: color-mix(in srgb, var(--color-primary) 52%, var(--border-default) 48%);
|
||||
box-shadow: var(--shadow-sm);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
color-mix(in srgb, var(--color-primary) 10%, var(--bg-card) 90%) 0%,
|
||||
color-mix(in srgb, var(--bg-card) 96%, transparent) 100%
|
||||
);
|
||||
box-shadow:
|
||||
0 0 0 1px color-mix(in srgb, var(--color-primary) 20%, transparent),
|
||||
0 12px 22px -18px color-mix(in srgb, var(--color-primary) 46%, transparent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.join-stage-item.is-active::before,
|
||||
.join-stage-item.is-current::before {
|
||||
height: 3px;
|
||||
opacity: 1;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
color-mix(in srgb, var(--color-primary) 84%, #7ed7ff 16%) 0%,
|
||||
color-mix(in srgb, var(--color-primary) 52%, #7ed7ff 48%) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.join-stage-item.is-completed .join-stage-status {
|
||||
color: #0f8a4f;
|
||||
}
|
||||
|
||||
.join-stage-item .join-stage-status.is-query-ready {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.join-stage-item.is-completed {
|
||||
border-color: color-mix(in srgb, #0f8a4f 48%, var(--border-default) 52%);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
color-mix(in srgb, #0f8a4f 7%, var(--bg-card) 93%) 0%,
|
||||
color-mix(in srgb, var(--bg-card) 96%, transparent) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.join-stage-item.is-completed::before {
|
||||
background: color-mix(in srgb, #0f8a4f 65%, transparent);
|
||||
}
|
||||
|
||||
.join-stage-item.is-active .join-stage-status {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
@@ -294,6 +523,34 @@
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.join-stage-item.is-upcoming,
|
||||
.join-stage-item.is-pending {
|
||||
border-color: color-mix(in srgb, var(--border-default) 88%, transparent);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
color-mix(in srgb, var(--bg-card) 95%, transparent) 0%,
|
||||
color-mix(in srgb, var(--bg-card) 99%, transparent) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.join-stage-item.is-upcoming::after,
|
||||
.join-stage-item.is-pending::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 24px;
|
||||
background:
|
||||
repeating-linear-gradient(
|
||||
-45deg,
|
||||
transparent 0 10px,
|
||||
color-mix(in srgb, var(--border-default) 35%, transparent) 10px 12px
|
||||
);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.join-stage-title-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
@@ -328,17 +585,34 @@
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.join-stage-location {
|
||||
margin: 4px 0 0;
|
||||
color: color-mix(in srgb, var(--text-primary) 88%, var(--text-secondary) 12%);
|
||||
font-size: 0.76rem;
|
||||
line-height: 1.42;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.join-forms-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.join-forms-grid.is-single {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.join-form-card {
|
||||
border: 1px solid var(--border-default);
|
||||
border: 1px solid color-mix(in srgb, var(--border-default) 86%, transparent);
|
||||
border-radius: 14px;
|
||||
background: color-mix(in srgb, var(--bg-card) 95%, transparent);
|
||||
background: linear-gradient(
|
||||
145deg,
|
||||
color-mix(in srgb, var(--bg-card) 82%, #1b2430 18%) 0%,
|
||||
color-mix(in srgb, var(--bg-card) 94%, transparent) 100%
|
||||
);
|
||||
padding: 18px;
|
||||
box-shadow: 0 16px 30px -24px color-mix(in srgb, #000000 65%, transparent);
|
||||
}
|
||||
|
||||
.join-form-card-full {
|
||||
@@ -353,8 +627,9 @@
|
||||
|
||||
.join-form-head p {
|
||||
margin: 6px 0 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
color: color-mix(in srgb, var(--text-primary) 72%, var(--text-secondary) 28%);
|
||||
font-size: 0.94rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.join-form-content {
|
||||
@@ -365,6 +640,89 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.join-progress-query-form {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.join-progress-query-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.join-progress-query-field {
|
||||
display: grid;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.join-progress-query-field span {
|
||||
font-size: 0.82rem;
|
||||
color: color-mix(in srgb, var(--text-primary) 85%, var(--text-secondary) 15%);
|
||||
}
|
||||
|
||||
.join-progress-query-field input {
|
||||
width: 100%;
|
||||
border: 1px solid color-mix(in srgb, var(--border-default) 86%, transparent);
|
||||
border-radius: 10px;
|
||||
background: color-mix(in srgb, var(--bg-card) 90%, transparent);
|
||||
color: var(--text-primary);
|
||||
padding: 9px 10px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.join-progress-query-field input:focus {
|
||||
outline: none;
|
||||
border-color: color-mix(in srgb, var(--color-primary) 55%, var(--border-default) 45%);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 16%, transparent);
|
||||
}
|
||||
|
||||
.join-progress-query-actions {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.join-progress-query-submit {
|
||||
border: 1px solid color-mix(in srgb, var(--color-primary) 48%, var(--border-default) 52%);
|
||||
border-radius: 10px;
|
||||
background: color-mix(in srgb, var(--color-primary) 18%, var(--bg-card) 82%);
|
||||
color: var(--text-primary);
|
||||
padding: 9px 16px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.join-progress-query-submit:hover {
|
||||
background: color-mix(in srgb, var(--color-primary) 24%, var(--bg-card) 76%);
|
||||
}
|
||||
|
||||
.join-progress-query-feedback {
|
||||
margin: 2px 0 0;
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid color-mix(in srgb, var(--border-default) 80%, transparent);
|
||||
background: color-mix(in srgb, var(--bg-card) 90%, transparent);
|
||||
color: var(--text-primary);
|
||||
font-size: 0.88rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.join-progress-query-feedback.is-success {
|
||||
border-color: color-mix(in srgb, #0f8a4f 58%, var(--border-default) 42%);
|
||||
background: color-mix(in srgb, #0f8a4f 14%, var(--bg-card) 86%);
|
||||
}
|
||||
|
||||
.join-progress-query-feedback.is-warning {
|
||||
border-color: color-mix(in srgb, #d89a1b 58%, var(--border-default) 42%);
|
||||
background: color-mix(in srgb, #d89a1b 14%, var(--bg-card) 86%);
|
||||
}
|
||||
|
||||
.join-progress-query-feedback.is-error {
|
||||
border-color: color-mix(in srgb, #c34646 58%, var(--border-default) 42%);
|
||||
background: color-mix(in srgb, #c34646 14%, var(--bg-card) 86%);
|
||||
}
|
||||
|
||||
.join-form-content .frm_forms {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -374,6 +732,62 @@
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_form_fields,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_form_field,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_field_wrapper {
|
||||
color: color-mix(in srgb, var(--text-primary) 95%, #ffffff 5%) !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_form_field {
|
||||
margin-bottom: 14px !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style label {
|
||||
color: color-mix(in srgb, var(--text-primary) 95%, #ffffff 5%) !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_primary_label,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_section_heading h3,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_inline_box label,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_radio label,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_checkbox label,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_opt_container label {
|
||||
color: color-mix(in srgb, var(--text-primary) 92%, #ffffff 8%) !important;
|
||||
font-weight: 600 !important;
|
||||
opacity: 1 !important;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_required {
|
||||
color: #ff6767 !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_description,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_error,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_error_style {
|
||||
color: color-mix(in srgb, var(--text-primary) 82%, var(--text-secondary) 18%) !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_error_style,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_error {
|
||||
border-left: 3px solid #ff6767 !important;
|
||||
background: color-mix(in srgb, #ff6767 10%, transparent) !important;
|
||||
padding: 8px 10px !important;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_message,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_success_style,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_success {
|
||||
border-left: 3px solid #42b983 !important;
|
||||
background: color-mix(in srgb, #42b983 14%, transparent) !important;
|
||||
color: color-mix(in srgb, var(--text-primary) 94%, #ffffff 6%) !important;
|
||||
border-radius: 4px;
|
||||
padding: 10px 12px !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="text"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="email"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="number"],
|
||||
@@ -382,17 +796,114 @@
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="datetime-local"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style textarea,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style select {
|
||||
background: color-mix(in srgb, var(--bg-body) 90%, transparent);
|
||||
border-color: var(--border-default);
|
||||
color: var(--text-primary);
|
||||
background: color-mix(in srgb, var(--bg-body) 84%, #ffffff 16%) !important;
|
||||
border: 1px solid color-mix(in srgb, var(--border-default) 42%, var(--color-primary) 58%) !important;
|
||||
color: color-mix(in srgb, var(--text-primary) 96%, #ffffff 4%) !important;
|
||||
min-height: 42px;
|
||||
border-radius: 8px !important;
|
||||
padding: 10px 12px !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input::placeholder,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style textarea::placeholder {
|
||||
color: color-mix(in srgb, var(--text-secondary) 78%, var(--text-primary) 22%) !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="text"]:focus,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="email"]:focus,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="number"]:focus,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="tel"]:focus,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="date"]:focus,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="datetime-local"]:focus,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style textarea:focus,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style select:focus {
|
||||
border-color: color-mix(in srgb, var(--color-primary) 76%, #8ec9ff 24%) !important;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 24%, transparent) !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="checkbox"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="radio"] {
|
||||
accent-color: var(--color-primary);
|
||||
transform: scale(1.06);
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_checkbox label,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_radio label,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_opt_container label {
|
||||
line-height: 1.55 !important;
|
||||
font-size: 0.96rem !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_submit {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="submit"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style button.frm_button_submit {
|
||||
border-radius: 9px;
|
||||
border: 1px solid color-mix(in srgb, var(--color-primary) 62%, var(--border-default) 38%);
|
||||
background: color-mix(in srgb, var(--color-primary) 10%, transparent);
|
||||
color: var(--color-primary);
|
||||
border-radius: 10px;
|
||||
border: 1px solid color-mix(in srgb, var(--color-primary) 82%, #9cd3ff 18%) !important;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
color-mix(in srgb, var(--color-primary) 82%, #78c3ff 18%) 0%,
|
||||
color-mix(in srgb, var(--color-primary) 92%, #5ea7f8 8%) 100%
|
||||
) !important;
|
||||
color: #ffffff !important;
|
||||
font-weight: 700 !important;
|
||||
letter-spacing: 0.01em;
|
||||
min-height: 44px;
|
||||
padding: 0 20px !important;
|
||||
box-shadow: 0 8px 18px -12px color-mix(in srgb, var(--color-primary) 65%, transparent);
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[type="submit"]:hover,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style button.frm_button_submit:hover {
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_save_draft,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style button[name*="draft"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[name*="draft"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style button[value*="草稿"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[value*="草稿"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style button[value*="Draft"],
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[value*="Draft"] {
|
||||
border: 1px solid color-mix(in srgb, var(--border-default) 30%, var(--color-primary) 70%) !important;
|
||||
background: color-mix(in srgb, var(--bg-card) 88%, transparent) !important;
|
||||
color: var(--color-primary) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style .frm_save_draft:hover,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style button[name*="draft"]:hover,
|
||||
.join-form-content .frm_style_formidable-style.with_frm_style input[name*="draft"]:hover {
|
||||
background: color-mix(in srgb, var(--bg-card) 74%, var(--color-primary) 26%) !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
[data-theme="light"] .join-form-card {
|
||||
background: linear-gradient(
|
||||
145deg,
|
||||
color-mix(in srgb, #ffffff 94%, #e8f2ff 6%) 0%,
|
||||
color-mix(in srgb, #ffffff 98%, #e8f2ff 2%) 100%
|
||||
);
|
||||
box-shadow: 0 16px 30px -24px rgba(120, 140, 165, 0.35);
|
||||
}
|
||||
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style input[type="text"],
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style input[type="email"],
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style input[type="number"],
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style input[type="tel"],
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style input[type="date"],
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style input[type="datetime-local"],
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style textarea,
|
||||
[data-theme="light"] .join-form-content .frm_style_formidable-style.with_frm_style select {
|
||||
background: #ffffff !important;
|
||||
border-color: color-mix(in srgb, #8bbcff 46%, var(--border-default) 54%) !important;
|
||||
}
|
||||
|
||||
.join-form-tip {
|
||||
@@ -422,6 +933,26 @@
|
||||
padding: 30px 0 60px;
|
||||
}
|
||||
|
||||
.join-news-strip {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.join-news-strip-track {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 6px;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.join-news-item {
|
||||
flex: 0 0 220px;
|
||||
padding-right: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--border-default) 82%, transparent);
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.join-stage-list {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
@@ -446,13 +977,14 @@
|
||||
|
||||
.join-canvas-overlay {
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
padding: 10px 11px;
|
||||
left: 0;
|
||||
right: auto;
|
||||
width: min(86vw, 272px);
|
||||
padding: 10px 16px 10px 18px;
|
||||
}
|
||||
|
||||
.join-stage-photo {
|
||||
height: 230px;
|
||||
.join-canvas-shell {
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
.join-current-stage {
|
||||
@@ -472,4 +1004,8 @@
|
||||
.join-stage-item {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.join-progress-query-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
+154
-17
@@ -16,6 +16,8 @@
|
||||
const waveFill = document.getElementById('joinWaveFill');
|
||||
const waveBoat = document.getElementById('joinWaveBoat');
|
||||
const waveMarks = document.getElementById('joinWaveMarks');
|
||||
const waveProgress = waveTrack ? waveTrack.closest('.join-wave-progress') : null;
|
||||
const overlayPanel = document.querySelector('.join-canvas-overlay');
|
||||
const joinData = window.itstudioJoinData && typeof window.itstudioJoinData === 'object'
|
||||
? window.itstudioJoinData
|
||||
: {};
|
||||
@@ -31,21 +33,24 @@
|
||||
let trackLeft = 0;
|
||||
let trackWidth = 0;
|
||||
let stageMarkers = [];
|
||||
let stageLayout = null;
|
||||
|
||||
const waveShape1 = { base: 0.16, amp: 7.5, len: 280, speed: 0.9 };
|
||||
const waveShape2 = { base: 0.44, amp: 6, len: 340, speed: 0.75 };
|
||||
const waveShape3 = { base: 0.68, amp: 6.5, len: 400, speed: 0.62 };
|
||||
const DAY_MS = 24 * 60 * 60 * 1000;
|
||||
const ONE_DAY_STAGE_WEIGHT_MS = DAY_MS * 1.8;
|
||||
|
||||
const palettes = {
|
||||
light: {
|
||||
wave1: 'rgba(198, 227, 255, 0.92)',
|
||||
wave2: 'rgba(142, 193, 236, 0.4)',
|
||||
wave3: 'rgba(84, 151, 214, 0.48)',
|
||||
wave1: 'rgba(122, 178, 230, 0.95)',
|
||||
wave2: 'rgba(73, 134, 197, 0.72)',
|
||||
wave3: 'rgba(40, 96, 161, 0.78)',
|
||||
},
|
||||
dark: {
|
||||
wave1: 'rgba(132, 190, 242, 0.88)',
|
||||
wave2: 'rgba(88, 151, 214, 0.4)',
|
||||
wave3: 'rgba(56, 118, 183, 0.48)',
|
||||
wave1: 'rgba(86, 146, 214, 0.92)',
|
||||
wave2: 'rgba(49, 104, 172, 0.78)',
|
||||
wave3: 'rgba(27, 73, 136, 0.82)',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -62,6 +67,61 @@
|
||||
return Number.isFinite(numeric) ? numeric : null;
|
||||
}
|
||||
|
||||
function getStages() {
|
||||
return Array.isArray(joinData.stages) ? joinData.stages : [];
|
||||
}
|
||||
|
||||
function getStageDurationMs(stage) {
|
||||
const start = getNumber(stage ? stage.startTs : null);
|
||||
const end = getNumber(stage ? stage.endTs : null);
|
||||
if (start === null || end === null) {
|
||||
return null;
|
||||
}
|
||||
return Math.max(0, end - start);
|
||||
}
|
||||
|
||||
function getEffectiveStageWeightMs(stage) {
|
||||
const duration = getStageDurationMs(stage);
|
||||
if (duration === null) {
|
||||
return ONE_DAY_STAGE_WEIGHT_MS;
|
||||
}
|
||||
if (duration <= DAY_MS) {
|
||||
return ONE_DAY_STAGE_WEIGHT_MS;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
function buildStageLayout(stages) {
|
||||
if (!stages.length) {
|
||||
return {
|
||||
markerByIndex: [],
|
||||
endByIndex: [],
|
||||
};
|
||||
}
|
||||
|
||||
const weights = stages.map((stage) => getEffectiveStageWeightMs(stage));
|
||||
const totalWeight = Math.max(1, weights.reduce((sum, w) => sum + w, 0));
|
||||
const markerByIndex = [];
|
||||
const endByIndex = [];
|
||||
let cumulative = 0;
|
||||
|
||||
for (let i = 0; i < stages.length; i += 1) {
|
||||
markerByIndex[i] = clamp(cumulative / totalWeight, 0, 1);
|
||||
cumulative += weights[i];
|
||||
endByIndex[i] = clamp(cumulative / totalWeight, 0, 1);
|
||||
}
|
||||
|
||||
endByIndex[endByIndex.length - 1] = 1;
|
||||
return { markerByIndex, endByIndex };
|
||||
}
|
||||
|
||||
function getStageLayout(stages) {
|
||||
if (!stageLayout || !stageLayout.markerByIndex || stageLayout.markerByIndex.length !== stages.length) {
|
||||
stageLayout = buildStageLayout(stages);
|
||||
}
|
||||
return stageLayout;
|
||||
}
|
||||
|
||||
function getNavigationType() {
|
||||
if (window.performance && typeof window.performance.getEntriesByType === 'function') {
|
||||
const entries = window.performance.getEntriesByType('navigation');
|
||||
@@ -90,6 +150,21 @@
|
||||
return getNavigationType() !== 'reload';
|
||||
}
|
||||
|
||||
function setupOverlayEntryAnimation() {
|
||||
if (!overlayPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
overlayPanel.classList.remove('is-enter-animate');
|
||||
if (!shouldAnimateEntry()) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
overlayPanel.classList.add('is-enter-animate');
|
||||
});
|
||||
}
|
||||
|
||||
function resize() {
|
||||
dpr = window.devicePixelRatio || 1;
|
||||
width = canvas.clientWidth;
|
||||
@@ -212,20 +287,34 @@
|
||||
}
|
||||
|
||||
function computeTargetProgress() {
|
||||
const stages = Array.isArray(joinData.stages) ? joinData.stages : [];
|
||||
const stages = getStages();
|
||||
if (!stages.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const denominator = stages.length > 1 ? (stages.length - 1) : 1;
|
||||
const layout = getStageLayout(stages);
|
||||
const markerByIndex = layout.markerByIndex;
|
||||
const endByIndex = layout.endByIndex;
|
||||
const currentIndex = getNumber(joinData.currentStageIndex);
|
||||
const nowTs = getNumber(joinData.nowTs) || Date.now();
|
||||
|
||||
// 有进行中阶段时,船严格对齐对应浮标节点。
|
||||
if (currentIndex !== null && currentIndex >= 0) {
|
||||
return clamp(currentIndex / denominator, 0, 1);
|
||||
// 有进行中阶段时,在该阶段对应区间内按时间连续推进。
|
||||
if (currentIndex !== null && currentIndex >= 0 && currentIndex < stages.length) {
|
||||
const stage = stages[currentIndex];
|
||||
const startProgress = getNumber(markerByIndex[currentIndex]) ?? 0;
|
||||
const endProgress = getNumber(endByIndex[currentIndex]) ?? startProgress;
|
||||
const startTs = getNumber(stage ? stage.startTs : null);
|
||||
const endTs = getNumber(stage ? stage.endTs : null);
|
||||
|
||||
if (startTs !== null && endTs !== null && endTs > startTs) {
|
||||
const ratio = clamp((nowTs - startTs) / (endTs - startTs), 0, 1);
|
||||
return clamp(startProgress + ((endProgress - startProgress) * ratio), 0, 1);
|
||||
}
|
||||
|
||||
// 无进行中阶段时,停在最近已完成阶段节点。
|
||||
return clamp(startProgress, 0, 1);
|
||||
}
|
||||
|
||||
// 无进行中阶段时,停在最近已完成阶段的末端。
|
||||
let lastCompletedIndex = -1;
|
||||
for (let i = 0; i < stages.length; i += 1) {
|
||||
if (stages[i] && stages[i].status === 'completed') {
|
||||
@@ -233,8 +322,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 阶段空档期:在“上一阶段浮标”和“下一阶段浮标”之间按时间线性推进。
|
||||
if (lastCompletedIndex >= 0) {
|
||||
return clamp(lastCompletedIndex / denominator, 0, 1);
|
||||
let nextUpcomingIndex = -1;
|
||||
for (let i = lastCompletedIndex + 1; i < stages.length; i += 1) {
|
||||
if (stages[i] && stages[i].status === 'upcoming') {
|
||||
nextUpcomingIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextUpcomingIndex >= 0) {
|
||||
const completedStage = stages[lastCompletedIndex];
|
||||
const upcomingStage = stages[nextUpcomingIndex];
|
||||
const gapStartTs = getNumber(completedStage ? completedStage.endTs : null);
|
||||
const gapEndTs = getNumber(upcomingStage ? upcomingStage.startTs : null);
|
||||
const fromProgress = clamp(getNumber(markerByIndex[lastCompletedIndex]) ?? 0, 0, 1);
|
||||
const toProgress = clamp(getNumber(markerByIndex[nextUpcomingIndex]) ?? fromProgress, 0, 1);
|
||||
|
||||
if (gapStartTs !== null && gapEndTs !== null && gapEndTs > gapStartTs && nowTs > gapStartTs && nowTs < gapEndTs) {
|
||||
const gapRatio = clamp((nowTs - gapStartTs) / (gapEndTs - gapStartTs), 0, 1);
|
||||
return clamp(fromProgress + ((toProgress - fromProgress) * gapRatio), 0, 1);
|
||||
}
|
||||
|
||||
if (nowTs <= gapStartTs) {
|
||||
return fromProgress;
|
||||
}
|
||||
|
||||
if (nowTs < gapEndTs) {
|
||||
return clamp((fromProgress + toProgress) * 0.5, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastCompletedIndex >= 0) {
|
||||
return clamp(getNumber(endByIndex[lastCompletedIndex]) ?? 0, 0, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -275,23 +397,29 @@
|
||||
|
||||
stageMarkers = [];
|
||||
waveMarks.innerHTML = '';
|
||||
if (waveProgress) {
|
||||
waveProgress.querySelectorAll('.join-wave-mark.is-lighthouse.is-docked').forEach((node) => node.remove());
|
||||
}
|
||||
|
||||
const stages = Array.isArray(joinData.stages) ? joinData.stages : [];
|
||||
const stages = getStages();
|
||||
if (!stages.length) {
|
||||
return;
|
||||
}
|
||||
const layout = getStageLayout(stages);
|
||||
const markerByIndex = layout.markerByIndex;
|
||||
|
||||
const currentIndex = getNumber(joinData.currentStageIndex);
|
||||
const safeCurrentIndex = currentIndex === null ? -1 : Math.round(currentIndex);
|
||||
const denominator = stages.length > 1 ? (stages.length - 1) : 1;
|
||||
|
||||
stages.forEach((stage, index) => {
|
||||
const marker = document.createElement('span');
|
||||
marker.className = 'join-wave-mark';
|
||||
const progress = denominator > 0 ? (index / denominator) : 0;
|
||||
marker.style.left = `${(progress * 100).toFixed(3)}%`;
|
||||
|
||||
const isLighthouse = index === stages.length - 1 || (stage && stage.key === 'public_notice');
|
||||
const progress = isLighthouse
|
||||
? 1
|
||||
: clamp(getNumber(markerByIndex[index]) ?? 0, 0, 1);
|
||||
|
||||
marker.classList.add(isLighthouse ? 'is-lighthouse' : 'is-buoy');
|
||||
if (index === safeCurrentIndex) {
|
||||
marker.classList.add('is-active');
|
||||
@@ -304,7 +432,15 @@
|
||||
|
||||
const beams = isLighthouse ? Array.from(icon.querySelectorAll('.marker-lh-beam')) : [];
|
||||
|
||||
if (isLighthouse && waveProgress) {
|
||||
marker.classList.add('is-docked');
|
||||
marker.style.right = '';
|
||||
marker.style.left = 'calc(100% - clamp(18px, 2.2vw, 30px))';
|
||||
waveProgress.appendChild(marker);
|
||||
} else {
|
||||
marker.style.left = `${(progress * 100).toFixed(3)}%`;
|
||||
waveMarks.appendChild(marker);
|
||||
}
|
||||
stageMarkers.push({
|
||||
element: marker,
|
||||
icon,
|
||||
@@ -490,6 +626,7 @@
|
||||
});
|
||||
|
||||
targetProgress = computeTargetProgress();
|
||||
setupOverlayEntryAnimation();
|
||||
renderStageMarks();
|
||||
startWaves();
|
||||
animateBoatToTarget();
|
||||
|
||||
+935
-48
File diff suppressed because it is too large
Load Diff
+264
-48
@@ -15,28 +15,76 @@ $join_stages = isset($join_runtime['stages']) && is_array($join_runtime['stages'
|
||||
$current_stage = isset($join_runtime['current_stage']) && is_array($join_runtime['current_stage'])
|
||||
? $join_runtime['current_stage']
|
||||
: array();
|
||||
$current_stage_mode = isset($join_runtime['current_stage_mode']) ? (string) $join_runtime['current_stage_mode'] : 'inactive';
|
||||
|
||||
$is_registration_open = !empty($join_runtime['is_registration_open']);
|
||||
$is_query_open = !empty($join_runtime['is_query_open']);
|
||||
$is_notice_open = !empty($join_runtime['is_notice_open']);
|
||||
|
||||
$query_deadline_cn = isset($join_runtime['query_deadline_cn']) ? (string) $join_runtime['query_deadline_cn'] : '';
|
||||
$query_deadline_en = isset($join_runtime['query_deadline_en']) ? (string) $join_runtime['query_deadline_en'] : '';
|
||||
$show_progress_visual = !empty($join_runtime['show_progress_visual']);
|
||||
$is_progress_query_open = !empty($join_runtime['show_progress_visual']);
|
||||
|
||||
$current_label_cn = isset($current_stage['label_cn']) ? (string) $current_stage['label_cn'] : '当前未在招新时段';
|
||||
$current_label_en = isset($current_stage['label_en']) ? (string) $current_stage['label_en'] : 'Recruitment is currently closed';
|
||||
$current_range_cn = isset($current_stage['range_cn']) ? (string) $current_stage['range_cn'] : '请关注后续通知';
|
||||
$current_range_en = isset($current_stage['range_en']) ? (string) $current_stage['range_en'] : 'Please check later updates';
|
||||
$current_location_cn = trim((string) ($current_stage['location_cn'] ?? ''));
|
||||
$current_location_en = trim((string) ($current_stage['location_en'] ?? ''));
|
||||
if ($current_location_en === '') {
|
||||
$current_location_en = $current_location_cn;
|
||||
}
|
||||
if ($current_location_cn === '') {
|
||||
$current_location_cn = $current_location_en;
|
||||
}
|
||||
$current_stage_heading_cn = $current_stage_mode === 'next' ? '下一招新阶段' : '当前招新阶段';
|
||||
$current_stage_heading_en = $current_stage_mode === 'next' ? 'Next Recruitment Stage' : 'Current Recruitment Stage';
|
||||
$current_stage_photo_url = isset($join_runtime['current_stage_photo_url']) ? (string) $join_runtime['current_stage_photo_url'] : '';
|
||||
if ($current_stage_photo_url === '') {
|
||||
$current_stage_photo_url = get_template_directory_uri() . '/resources/it_logo_2024.svg';
|
||||
}
|
||||
|
||||
$signup_shortcode = trim((string) ($join_settings['signup_form_shortcode'] ?? ''));
|
||||
$query_shortcode = trim((string) ($join_settings['query_form_shortcode'] ?? ''));
|
||||
$notice_shortcode = trim((string) ($join_settings['notice_view_shortcode'] ?? ''));
|
||||
|
||||
$has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsController');
|
||||
$progress_lookup = function_exists('itstudio_join_resolve_progress_lookup')
|
||||
? itstudio_join_resolve_progress_lookup($join_runtime, $_GET)
|
||||
: array(
|
||||
'submitted' => false,
|
||||
'has_query' => false,
|
||||
'name' => '',
|
||||
'qq' => '',
|
||||
'email' => '',
|
||||
'student_id' => '',
|
||||
'message_cn' => '',
|
||||
'message_en' => '',
|
||||
'tone' => 'info',
|
||||
);
|
||||
$join_feed_data = function_exists('itstudio_join_get_recruitment_feed_items')
|
||||
? itstudio_join_get_recruitment_feed_items($join_runtime, 5)
|
||||
: array('display_year' => (int) wp_date('Y'), 'items' => array());
|
||||
$join_feed_items = isset($join_feed_data['items']) && is_array($join_feed_data['items'])
|
||||
? $join_feed_data['items']
|
||||
: array();
|
||||
$join_feed_items = array_values(array_filter($join_feed_items, static function ($item) {
|
||||
if (!is_array($item)) {
|
||||
return false;
|
||||
}
|
||||
$title = trim((string) ($item['title'] ?? ''));
|
||||
$url = trim((string) ($item['url'] ?? ''));
|
||||
return ($title !== '' && $url !== '');
|
||||
}));
|
||||
|
||||
$join_form_status = '';
|
||||
if (isset($_GET['join_form_status']) && is_string($_GET['join_form_status'])) {
|
||||
$join_form_status = strtolower(trim((string) wp_unslash($_GET['join_form_status'])));
|
||||
}
|
||||
if ($join_form_status !== 'submitted' && $join_form_status !== 'draft') {
|
||||
$join_form_status = (isset($_GET['join_form_submitted']) && (string) $_GET['join_form_submitted'] === '1') ? 'submitted' : '';
|
||||
}
|
||||
|
||||
$is_post_request = isset($_SERVER['REQUEST_METHOD']) && strtoupper((string) $_SERVER['REQUEST_METHOD']) === 'POST';
|
||||
$post_form_status = 'submitted';
|
||||
if ($is_post_request && function_exists('itstudio_join_detect_form_submission_status')) {
|
||||
$post_form_status = itstudio_join_detect_form_submission_status($_POST);
|
||||
}
|
||||
?>
|
||||
|
||||
<main class="site-main join-page">
|
||||
@@ -45,6 +93,51 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
<h1 class="join-title" data-cn="加入我们" data-en="Join Us">加入我们</h1>
|
||||
</header>
|
||||
|
||||
<?php if ($join_form_status === 'submitted' || $join_form_status === 'draft') : ?>
|
||||
<?php
|
||||
$notice_cn = $join_form_status === 'draft' ? '草稿已保存' : '你的报名表单已提交,感谢报名';
|
||||
$notice_en = $join_form_status === 'draft' ? 'Draft saved.' : 'Your registration form has been submitted. Thank you for applying.';
|
||||
?>
|
||||
<p class="join-submit-notice" data-cn="<?php echo esc_attr($notice_cn); ?>" data-en="<?php echo esc_attr($notice_en); ?>"><?php echo esc_html($notice_cn); ?></p>
|
||||
<script>
|
||||
(function () {
|
||||
if (!window.history || !window.history.replaceState) {
|
||||
return;
|
||||
}
|
||||
var url = new URL(window.location.href);
|
||||
if (!url.searchParams.has('join_form_status') && !url.searchParams.has('join_form_submitted')) {
|
||||
return;
|
||||
}
|
||||
url.searchParams.delete('join_form_status');
|
||||
url.searchParams.delete('join_form_submitted');
|
||||
var nextUrl = url.pathname + (url.search ? url.search : '') + url.hash;
|
||||
window.history.replaceState({}, document.title, nextUrl);
|
||||
})();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<section class="join-news-strip" aria-label="Recruitment News">
|
||||
<?php if (!empty($join_feed_items)) : ?>
|
||||
<div class="join-news-strip-track">
|
||||
<?php foreach ($join_feed_items as $feed_item) : ?>
|
||||
<?php
|
||||
$feed_title = isset($feed_item['title']) ? (string) $feed_item['title'] : '';
|
||||
$feed_excerpt = isset($feed_item['excerpt']) ? (string) $feed_item['excerpt'] : '';
|
||||
$feed_url = isset($feed_item['url']) ? (string) $feed_item['url'] : '';
|
||||
?>
|
||||
<article class="join-news-item">
|
||||
<h3 class="join-news-item-title">
|
||||
<a href="<?php echo esc_url($feed_url); ?>"><?php echo esc_html($feed_title); ?></a>
|
||||
</h3>
|
||||
<p class="join-news-item-excerpt"><?php echo esc_html($feed_excerpt); ?></p>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p class="join-news-strip-empty" data-cn="暂无可展示的招新新闻通告" data-en="No recruitment updates available yet.">暂无可展示的招新新闻通告</p>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<section class="join-hero">
|
||||
<div class="join-canvas-shell">
|
||||
<div class="join-stage-photo-frame">
|
||||
@@ -55,7 +148,7 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
loading="lazy"
|
||||
>
|
||||
<div class="join-canvas-overlay">
|
||||
<p class="join-current-label" data-cn="当前招新阶段" data-en="Current Recruitment Stage">当前招新阶段</p>
|
||||
<p class="join-current-label" data-cn="<?php echo esc_attr($current_stage_heading_cn); ?>" data-en="<?php echo esc_attr($current_stage_heading_en); ?>"><?php echo esc_html($current_stage_heading_cn); ?></p>
|
||||
<h2
|
||||
id="joinCurrentStage"
|
||||
class="join-current-stage"
|
||||
@@ -72,10 +165,25 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
>
|
||||
<?php echo esc_html($current_range_cn); ?>
|
||||
</p>
|
||||
<?php if ($current_location_cn !== '' || $current_location_en !== '') : ?>
|
||||
<?php
|
||||
$current_location_line_cn = '地点:' . $current_location_cn;
|
||||
$current_location_line_en = 'Location: ' . $current_location_en;
|
||||
?>
|
||||
<p
|
||||
id="joinCurrentLocation"
|
||||
class="join-current-location"
|
||||
data-cn="<?php echo esc_attr($current_location_line_cn); ?>"
|
||||
data-en="<?php echo esc_attr($current_location_line_en); ?>"
|
||||
>
|
||||
<?php echo esc_html($current_location_line_cn); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="join-wave-layer">
|
||||
<canvas id="joinProgressCanvas" class="join-progress-canvas" aria-hidden="true"></canvas>
|
||||
<?php if ($show_progress_visual) : ?>
|
||||
<div class="join-wave-progress" aria-hidden="true">
|
||||
<div id="joinWaveTrack" class="join-wave-track">
|
||||
<span id="joinWaveFill" class="join-wave-fill"></span>
|
||||
@@ -95,6 +203,7 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -114,7 +223,32 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
$status_cn = '未开始';
|
||||
$status_en = 'Upcoming';
|
||||
}
|
||||
$stage_key = (string) ($stage['key'] ?? '');
|
||||
$stage_result_uploaded = !empty($stage['result_uploaded']);
|
||||
$stage_location_cn = trim((string) ($stage['location_cn'] ?? ''));
|
||||
$stage_location_en = trim((string) ($stage['location_en'] ?? ''));
|
||||
if ($stage_location_en === '') {
|
||||
$stage_location_en = $stage_location_cn;
|
||||
}
|
||||
if ($stage_location_cn === '') {
|
||||
$stage_location_cn = $stage_location_en;
|
||||
}
|
||||
$is_current_stage = !empty($current_stage['key']) && !empty($stage['key']) && ((string) $current_stage['key'] === (string) $stage['key']);
|
||||
$is_public_notice_stage = ($stage_key === 'public_notice');
|
||||
$is_mid_stage_query_ready = in_array($stage_key, array('first_interview', 'assessment', 'second_interview'), true)
|
||||
&& $stage_status === 'completed'
|
||||
&& $stage_result_uploaded;
|
||||
$is_query_ready_status = false;
|
||||
if ($is_mid_stage_query_ready) {
|
||||
$status_cn = '可查询结果';
|
||||
$status_en = 'Query Available';
|
||||
$is_query_ready_status = true;
|
||||
}
|
||||
if ($is_public_notice_stage && in_array($stage_status, array('active', 'completed'), true)) {
|
||||
$status_cn = '可查询结果';
|
||||
$status_en = 'Query Available';
|
||||
$is_query_ready_status = true;
|
||||
}
|
||||
?>
|
||||
<li class="join-stage-item is-<?php echo esc_attr($stage_status); ?><?php echo $is_current_stage ? ' is-current' : ''; ?>">
|
||||
<div class="join-stage-title-row">
|
||||
@@ -126,7 +260,7 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
<?php echo esc_html((string) ($stage['label_cn'] ?? '')); ?>
|
||||
</h3>
|
||||
<span
|
||||
class="join-stage-status"
|
||||
class="join-stage-status<?php echo $is_query_ready_status ? ' is-query-ready' : ''; ?>"
|
||||
data-cn="<?php echo esc_attr($status_cn); ?>"
|
||||
data-en="<?php echo esc_attr($status_en); ?>"
|
||||
>
|
||||
@@ -140,21 +274,39 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
>
|
||||
<?php echo esc_html((string) ($stage['range_cn'] ?? '')); ?>
|
||||
</p>
|
||||
<?php if ($stage_location_cn !== '' || $stage_location_en !== '') : ?>
|
||||
<?php
|
||||
$stage_location_line_cn = '地点:' . $stage_location_cn;
|
||||
$stage_location_line_en = 'Location: ' . $stage_location_en;
|
||||
?>
|
||||
<p
|
||||
class="join-stage-location"
|
||||
data-cn="<?php echo esc_attr($stage_location_line_cn); ?>"
|
||||
data-en="<?php echo esc_attr($stage_location_line_en); ?>"
|
||||
>
|
||||
<?php echo esc_html($stage_location_line_cn); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="join-forms-grid">
|
||||
<?php
|
||||
$show_registration_form = $is_registration_open;
|
||||
$show_progress_query_form = $is_progress_query_open;
|
||||
$visible_form_count = ($show_registration_form ? 1 : 0) + ($show_progress_query_form ? 1 : 0);
|
||||
?>
|
||||
<?php if ($visible_form_count > 0) : ?>
|
||||
<section class="join-forms-grid<?php echo $visible_form_count === 1 ? ' is-single' : ''; ?>">
|
||||
<?php if ($show_registration_form) : ?>
|
||||
<article class="join-form-card">
|
||||
<header class="join-form-head">
|
||||
<h2 data-cn="报名表单" data-en="Registration Form">报名表单</h2>
|
||||
<p data-cn="仅在报名阶段开放" data-en="Available during registration stage only.">仅在报名阶段开放</p>
|
||||
</header>
|
||||
<div class="join-form-content">
|
||||
<?php if (!$is_registration_open) : ?>
|
||||
<p class="join-form-tip" data-cn="当前不在报名时间段 请关注后续通知" data-en="Registration is currently closed.">当前不在报名时间段 请关注后续通知</p>
|
||||
<?php elseif (!$has_formidable) : ?>
|
||||
<?php if (!$has_formidable) : ?>
|
||||
<p class="join-form-tip" data-cn="未检测到 Formidable Forms 插件 请先启用插件" data-en="Formidable Forms is not active.">未检测到 Formidable Forms 插件 请先启用插件</p>
|
||||
<?php elseif ($signup_shortcode === '') : ?>
|
||||
<p class="join-form-tip" data-cn="请在 设置 > 招新设置 中填写报名表单 Shortcode" data-en="Please configure the registration form shortcode in Settings > Recruitment Settings.">请在 设置 > 招新设置 中填写报名表单 Shortcode</p>
|
||||
@@ -163,52 +315,116 @@ $has_formidable = shortcode_exists('formidable') || class_exists('FrmFormsContro
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($show_progress_query_form) : ?>
|
||||
<article class="join-form-card">
|
||||
<header class="join-form-head">
|
||||
<h2 data-cn="结果查询" data-en="Progress Lookup">结果查询</h2>
|
||||
<p data-cn="报名开始后至公示结束前可查询进度" data-en="Available from registration start until the end of public notice.">报名开始后至公示结束前可查询进度</p>
|
||||
<h2 data-cn="录取进度查询" data-en="Admission Progress Lookup">录取进度查询</h2>
|
||||
<p data-cn="报名阶段至录取结果公布阶段可查询" data-en="Available from registration stage to final result release stage.">报名阶段至录取结果公布阶段可查询</p>
|
||||
</header>
|
||||
<div class="join-form-content">
|
||||
<?php if (!$is_query_open) : ?>
|
||||
<p class="join-form-tip" data-cn="当前查询通道未开放或已关闭" data-en="Lookup is currently unavailable.">当前查询通道未开放或已关闭</p>
|
||||
<?php elseif (!$has_formidable) : ?>
|
||||
<p class="join-form-tip" data-cn="未检测到 Formidable Forms 插件 请先启用插件" data-en="Formidable Forms is not active.">未检测到 Formidable Forms 插件 请先启用插件</p>
|
||||
<?php elseif ($query_shortcode === '') : ?>
|
||||
<p class="join-form-tip" data-cn="请在 设置 > 招新设置 中填写查询表单 Shortcode" data-en="Please configure the lookup form shortcode in Settings > Recruitment Settings.">请在 设置 > 招新设置 中填写查询表单 Shortcode</p>
|
||||
<?php else : ?>
|
||||
<?php echo do_shortcode($query_shortcode); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($query_deadline_cn !== '' || $query_deadline_en !== '') : ?>
|
||||
<footer
|
||||
class="join-form-footnote"
|
||||
data-cn="<?php echo esc_attr('查询截止时间 ' . $query_deadline_cn); ?>"
|
||||
data-en="<?php echo esc_attr('Lookup closes at: ' . $query_deadline_en); ?>"
|
||||
<form method="get" class="join-progress-query-form">
|
||||
<div class="join-progress-query-grid">
|
||||
<label class="join-progress-query-field">
|
||||
<span data-cn="姓名" data-en="Name">姓名</span>
|
||||
<input
|
||||
type="text"
|
||||
name="join_query_name"
|
||||
value="<?php echo esc_attr((string) ($progress_lookup['name'] ?? '')); ?>"
|
||||
data-cn-placeholder="请输入姓名"
|
||||
data-en-placeholder="Enter name"
|
||||
placeholder="请输入姓名"
|
||||
>
|
||||
<?php echo esc_html('查询截止时间 ' . $query_deadline_cn); ?>
|
||||
</footer>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
|
||||
<article class="join-form-card join-form-card-full">
|
||||
<header class="join-form-head">
|
||||
<h2 data-cn="录取结果公示" data-en="Admission Public Notice">录取结果公示</h2>
|
||||
<p data-cn="公示阶段自动展示 公示期为 7 天" data-en="Published automatically during the 7-day notice window.">公示阶段自动展示 公示期为 7 天</p>
|
||||
</header>
|
||||
<div class="join-form-content">
|
||||
<?php if (!$is_notice_open) : ?>
|
||||
<p class="join-form-tip" data-cn="当前未进入公示阶段" data-en="Public notice is not active yet.">当前未进入公示阶段</p>
|
||||
<?php elseif (!$has_formidable) : ?>
|
||||
<p class="join-form-tip" data-cn="未检测到 Formidable Forms 插件 请先启用插件" data-en="Formidable Forms is not active.">未检测到 Formidable Forms 插件 请先启用插件</p>
|
||||
<?php elseif ($notice_shortcode === '') : ?>
|
||||
<p class="join-form-tip" data-cn="请在 设置 > 招新设置 中填写公示视图 Shortcode" data-en="Please configure the notice view shortcode in Settings > Recruitment Settings.">请在 设置 > 招新设置 中填写公示视图 Shortcode</p>
|
||||
<?php else : ?>
|
||||
<?php echo do_shortcode($notice_shortcode); ?>
|
||||
</label>
|
||||
<label class="join-progress-query-field">
|
||||
<span data-cn="QQ" data-en="QQ">QQ</span>
|
||||
<input
|
||||
type="text"
|
||||
name="join_query_qq"
|
||||
value="<?php echo esc_attr((string) ($progress_lookup['qq'] ?? '')); ?>"
|
||||
data-cn-placeholder="请输入QQ"
|
||||
data-en-placeholder="Enter QQ"
|
||||
placeholder="请输入QQ"
|
||||
>
|
||||
</label>
|
||||
<label class="join-progress-query-field">
|
||||
<span data-cn="邮箱" data-en="Email">邮箱</span>
|
||||
<input
|
||||
type="text"
|
||||
name="join_query_email"
|
||||
value="<?php echo esc_attr((string) ($progress_lookup['email'] ?? '')); ?>"
|
||||
data-cn-placeholder="请输入邮箱"
|
||||
data-en-placeholder="Enter email"
|
||||
placeholder="请输入邮箱"
|
||||
>
|
||||
</label>
|
||||
<label class="join-progress-query-field">
|
||||
<span data-cn="学号" data-en="Student ID">学号</span>
|
||||
<input
|
||||
type="text"
|
||||
name="join_query_student_id"
|
||||
value="<?php echo esc_attr((string) ($progress_lookup['student_id'] ?? '')); ?>"
|
||||
data-cn-placeholder="请输入学号"
|
||||
data-en-placeholder="Enter student ID"
|
||||
placeholder="请输入学号"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
<div class="join-progress-query-actions">
|
||||
<button type="submit" name="join_progress_lookup" value="1" class="join-progress-query-submit" data-cn="查询录取进度" data-en="Check Progress">查询录取进度</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php if (!empty($progress_lookup['submitted'])) : ?>
|
||||
<?php
|
||||
$lookup_tone = trim((string) ($progress_lookup['tone'] ?? 'info'));
|
||||
if (!in_array($lookup_tone, array('success', 'warning', 'error', 'info'), true)) {
|
||||
$lookup_tone = 'info';
|
||||
}
|
||||
?>
|
||||
<p
|
||||
class="join-progress-query-feedback is-<?php echo esc_attr($lookup_tone); ?>"
|
||||
data-cn="<?php echo esc_attr((string) ($progress_lookup['message_cn'] ?? '')); ?>"
|
||||
data-en="<?php echo esc_attr((string) ($progress_lookup['message_en'] ?? '')); ?>"
|
||||
>
|
||||
<?php echo esc_html((string) ($progress_lookup['message_cn'] ?? '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($is_post_request) : ?>
|
||||
<script>
|
||||
(function () {
|
||||
var hasSuccessMessage = document.querySelector('.frm_message, .frm_success_style, .frm_success');
|
||||
if (!hasSuccessMessage) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var url = new URL(window.location.href);
|
||||
['join_form_status', 'join_form_submitted', 'frm_action', 'frm_state', 'frm_data', 'frm_page_order', 'frm_test', 'frm_nonce'].forEach(function (key) {
|
||||
url.searchParams.delete(key);
|
||||
});
|
||||
var status = <?php echo wp_json_encode($post_form_status); ?>;
|
||||
if (status !== 'draft' && status !== 'submitted') {
|
||||
status = 'submitted';
|
||||
}
|
||||
var successText = (hasSuccessMessage.textContent || '').toLowerCase();
|
||||
if (successText.indexOf('draft') !== -1 || successText.indexOf('草稿') !== -1) {
|
||||
status = 'draft';
|
||||
}
|
||||
url.searchParams.set('join_form_status', status);
|
||||
var nextUrl = url.pathname + (url.search ? url.search : '') + url.hash;
|
||||
window.location.replace(nextUrl);
|
||||
} catch (error) {
|
||||
// keep current page if URL parsing fails
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user