Plugin Directory

Changeset 3693621


Ignore:
Timestamp:
09/13/2026 12:06:51 PM (6 weeks ago)
Author:
thesiim
Message:

Version 1.77.0 release

Location:
seatreg
Files:
1333 added
39 edited

Legend:

Unmodified
Added
Removed
  • seatreg/trunk/css/scss/admin/components/seatreg-flower.scss

    r3504502 r3693621  
     1.seatreg-flower-layer {
     2    position: absolute;
     3    inset: 0;
     4    z-index: -1;
     5    overflow: hidden;
     6    pointer-events: none;
     7}
     8
    19.seatreg-flower-container {
    210    --flower-size: 12px;
    311    --flower-delay: 0s;
    412    --flower-opacity: 0.2;
    5     width: var(--flower-size);
    6     height: var(--flower-size);
     13    --flower-petal-reach: calc(var(--flower-size) * 1.42);
     14    width: calc(var(--flower-petal-reach) * 2);
     15    height: calc(var(--flower-petal-reach) * 2);
    716    position: absolute;
    817}
    … …  
    1524    width: var(--flower-size);
    1625    position: absolute;
    17     top: var(--flower-size);
    18     left: var(--flower-size);
     26    top: 50%;
     27    left: 50%;
    1928    transform-origin: left top;
    2029    opacity: 0;
  • seatreg/trunk/css/scss/admin/seatreg_admin.scss

    r3680221 r3693621  
    2222@import "components/seatreg-update-notice";
    2323@import "components/registration-cards";
     24@import "components/overview";
    2425
    2526html {
    2627  font-size: 100%;
    2728}
     29
    2830.index-icon {
    2931  margin-right: 10px;
    3032}
     33
    3134.btn-default {
    3235  color: #333;
    … …  
    3437  border-color: #ccc;
    3538}
     39
    3640.btn-default:focus {
    3741  color: #333;
    … …  
    3943  border-color: #8c8c8c;
    4044}
     45
    4146.btn-default:hover {
    4247  color: #333;
    … …  
    4449  border-color: #adadad;
    4550}
     51
    4652.btn-default:active {
    4753  color: #333;
    … …  
    4955  border-color: #adadad;
    5056}
     57
    5158.seatreg-wp-admin .btn-primary {
    5259  color: #fff;
    … …  
    5461  border-color: #357ebd;
    5562}
     63
    5664.seatreg-wp-admin .btn-primary:hover,
    5765.seatreg-wp-admin .btn-primary:active {
    … …  
    5967  border-color: #285e8e;
    6068}
     69
    6170.seatreg-wp-admin input[type="checkbox"]:focus {
    6271  outline: none;
    6372}
     73
    6474.seatreg-wp-admin {
    6575  font-family: "Open Sans", sans-serif;
    6676}
     77
    6778.seatreg-wp-admin .home-content {
    6879  display: flow-root;
    6980  position: relative;
    7081}
     82
    7183.seatreg-wp-admin .jumbotron {
    7284  background-image: url(../img/chairs_med.jpg);
    … …  
    7587  margin-bottom: 42px;
    7688}
     89
    7790.seatreg-wp-admin .donate-wrap {
    7891  max-width: 100%;
    … …  
    8497  row-gap: 12px;
    8598  position: relative;
     99  isolation: isolate;
    86100
    87101  p {
    … …  
    92106    margin-right: 12px;
    93107  }
     108
    94109  .donate-paypal {
    95110    display: flex;
    … …  
    107122      margin: 0;
    108123    }
    109   }
     124
     125  }
     126
    110127  .donate-img {
    111128    cursor: pointer;
    … …  
    120137      filter: brightness(1.08);
    121138    }
    122   }
     139
     140  }
     141
    123142  .buy-me-coffee-link {
    124143    img {
    125144      width: 120px;
    126145    }
    127   }
    128 }
     146
     147  }
     148}
     149
    129150.seatreg-wp-admin .your-registrations-header {
    130151  margin-top: 28px;
    … …  
    135156  margin-left: 0;
    136157}
     158
    137159.seatreg-wp-admin .nav-tab {
    138160  background: #f2f2f2;
    139161}
     162
    140163.seatreg-wp-admin .nav-tab.nav-tab-active {
    141164  text-decoration: underline;
    142165}
     166
    143167.new-reg-title {
    144168  margin-bottom: 24px;
    145169}
     170
    146171.seatreg-wp-admin .jumbotron .main-heading {
    147172  font-size: 38px;
    148173  font-weight: 600;
    149174}
     175
    150176.seatreg-wp-admin .jumbotron .jumbotron-text {
    151177  font-size: 21px;
    152178  font-weight: 600;
    153179}
     180
    154181.seatreg-wp-admin .nav-tabs {
    155182  margin-top: 40px;
    156183}
     184
    157185.seatreg-tabs-content {
    158186  background-color: #f2f2f2;
    … …  
    162190  position: relative;
    163191}
     192
    164193.seatreg-tabs-content .etabs {
    165194  margin: 0;
    … …  
    168197  padding-bottom: 6px;
    169198}
     199
    170200.seatreg-tabs-content .tab {
    171201  display: inline-block;
    … …  
    176206  background: #fff;
    177207}
     208
    178209.seatreg-tabs-content .tab a {
    179210  font-size: 16px;
    … …  
    185216  color: #000;
    186217}
     218
    187219.seatreg-tabs-content .tab a:hover {
    188220  text-decoration: underline;
    189221}
     222
    190223.seatreg-tabs-content .tab.active {
    191224  background: #404040;
    192225  position: relative;
    193226}
     227
    194228.seatreg-tabs-content .tab a.active {
    195229  font-weight: bold;
    196230  color: #fff;
    197231}
     232
    198233.seatreg-tabs-content .tab-container .panel-container {
    199234  overflow: hidden;
    200235}
     236
    201237.seatreg-tabs-content .form-group {
    202238  margin-bottom: 25px;
    203239}
     240
    204241.seatreg-settings-form .form-group {
    205242  max-width: 600px;
    206243}
     244
     245.seatreg-settings-form .form-group-title {
     246  margin: 0 0 5px;
     247  font-size: 16px;
     248}
     249
     250.seatreg-settings-form .form-group-subfield-label {
     251  margin-bottom: 2px;
     252  font-size: 13px;
     253}
     254
    207255.seatreg-settings-form .flow-summary-group {
    208256  max-width: none;
    209257}
     258
    210259.settings-tabs {
    211260  display: flex;
    … …  
    216265  background-color: #f2f2f2;
    217266}
     267
    218268.settings-tab {
    219269  background: #fff;
    … …  
    225275  color: #000;
    226276}
     277
    227278.settings-tab:hover {
    228279  text-decoration: underline;
    229280}
     281
    230282.settings-tab.settings-tab--active {
    231283  background: #404040;
    … …  
    233285  color: #fff;
    234286}
     287
    235288.settings-tab.settings-tab--active:hover {
    236289  text-decoration: none;
    237290}
     291
    238292.settings-tab-panels {
    239293  padding: 32px 0 0;
    240294  background: transparent;
    241295}
     296
    242297.settings-tab-panel {
    243298  display: none;
    244299}
     300
    245301.settings-tab-panel.settings-tab-panel--active {
    246302  display: block;
    247303}
     304
    248305.email-color-fields {
    249306  display: grid;
    … …  
    253310  margin-top: 12px;
    254311}
     312
    255313.email-logo-controls {
    256314  display: flex;
    … …  
    260318  flex-wrap: wrap;
    261319}
     320
    262321#email-logo-preview,
    263322#page-logo-preview {
    … …  
    269328  background: #fff;
    270329}
     330
    271331.email-color-field {
    272332  display: contents;
    … …  
    289349      cursor: not-allowed;
    290350    }
    291   }
    292 }
     351
     352  }
     353}
     354
    293355.seatreg-settings-form #seatreg-settings-submit {
    294356  margin-top: 20px;
    295357}
     358
    296359.booking-flow-details__summary {
    297360  cursor: pointer;
    … …  
    305368  color: #2271b1;
    306369}
     370
    307371.booking-flow-details__summary::-webkit-details-marker {
    308372  display: none;
    309373}
     374
    310375.booking-flow-details__summary:hover {
    311376  color: #135e96;
    312377}
     378
    313379.booking-flow-details__icon {
    314380  margin-right: 8px;
    315381  transition: transform 0.15s ease;
    316382}
     383
    317384.booking-flow-details[open] .booking-flow-details__icon {
    318385  transform: rotate(90deg);
    319386}
     387
    320388.booking-flow-details__hint {
    321389  font-weight: 400;
    … …  
    324392  margin-left: 8px;
    325393}
     394
    326395.booking-flow-details .help-block {
    327396  margin-top: 10px;
    328397}
     398
    329399#booking-flow-summary .flow-group {
    330400  margin-bottom: 12px;
    331401}
     402
    332403#booking-flow-summary .flow-group:last-child {
    333404  margin-bottom: 0;
    334405}
     406
    335407#booking-flow-summary .flow-group__title {
    336408  font-weight: 600;
    337409  margin-bottom: 4px;
    338410}
     411
    339412#booking-flow-summary .flow-group__list {
    340413  margin: 0;
    … …  
    342415  list-style: disc;
    343416}
     417
    344418#booking-flow-summary .flow-group__list li {
    345419  margin-bottom: 3px;
    346420}
     421
    347422#booking-flow-summary .flow-jump {
    348423  margin-left: 6px;
    … …  
    351426  text-decoration: none;
    352427}
     428
    353429#booking-flow-summary .flow-jump:hover {
    354430  color: #135e96;
    355431}
     432
    356433.flow-jump-highlight {
    357434  animation: seatregFlowHighlight 1.6s ease;
    358435  border-radius: 4px;
    359436}
     437
    360438@keyframes seatregFlowHighlight {
    361439  0% {
    362440    background-color: #fff3b0;
    363441  }
     442
    364443  100% {
    365444    background-color: transparent;
    … …  
    372451  font-family: "Open Sans", sans-serif;
    373452}
     453
    374454.seatreg-tabs-content #my-regs {
    375455  width: 1170px;
    … …  
    377457  padding: 0 15px;
    378458}
     459
    379460.seatreg-tabs-content #server-response-text {
    380461  font-size: 20px;
    381462}
     463
    382464.seatreg-tabs-content .log-out-btn {
    383465  display: block;
    … …  
    389471  font-size: 18px;
    390472}
     473
    391474.seatreg-tabs-content .log-out-btn .l-pic {
    392475  float: left;
    … …  
    403486}
    404487
    405 .seatreg-tabs-content .reg-overview-middle-wrap {
    406   display: flex;
    407   flex-wrap: nowrap;
    408   align-items: center;
    409 }
    410 
    411 .seatreg-tabs-content .reg-overview-top {
    412   padding-bottom: 20px;
    413   overflow: hidden;
    414 }
    415 
    416 .seatreg-tabs-content .overview-calendar-wrap {
    417   display: flex;
    418   justify-content: center;
    419   align-items: center;
    420   margin-bottom: 20px;
    421 
    422   label {
    423     margin-bottom: 0;
    424     text-transform: uppercase;
    425   }
    426 
    427   input {
    428     text-align: center;
    429     margin-left: 12px;
    430     width: 170px;
    431   }
    432 }
    433 
    434 .seatreg-tabs-content .reg-overview-aside {
    435   width: 220px;
    436   float: left;
    437   padding-right: 20px;
    438   text-overflow: ellipsis;
    439   min-height: 180px;
    440   margin-bottom: 20px;
    441   position: relative;
    442   overflow: auto;
    443 }
    444 .seatreg-tabs-content .room-list {
    445   list-style: none;
    446   margin: 0;
    447   padding: 0;
    448 }
    449 .seatreg-tabs-content .room-list-active {
    450   color: #f47a37;
    451 }
    452 .seatreg-tabs-content .room-list-item {
    453   margin-bottom: 2px;
    454   font-size: 18px;
    455 }
    456 .seatreg-tabs-content .first-item {
    457   margin-bottom: 6px;
    458   font-size: 20px;
    459   text-transform: uppercase;
    460 }
    461 .seatreg-tabs-content .room-list-item:hover {
    462   cursor: pointer;
    463   color: #f47a37;
    464 }
    465 
    466 .seatreg-tabs-content .reg-overview-top-header {
    467   font-size: 24px;
    468   font-weight: bold;
    469   float: left;
    470   min-width: 200px;
    471   height: 50px;
    472   line-height: 50px;
    473   margin-right: 10px;
    474   display: none;
    475 }
    476 .seatreg-tabs-content .reg-overview-top-header:first-letter {
    477   text-transform: capitalize;
    478 }
    479 
    480 .seatreg-tabs-content .reg-overview-top-bron-notify {
    481   color: #ea6060;
    482   font-size: 14px;
    483   float: left;
    484   height: 50px;
    485   line-height: 50px;
    486 }
    487 .seatreg-tabs-content .reg-overview-middle {
    488   float: left;
    489   width: 640px;
    490   margin-bottom: 30px;
    491   margin-left: 40px;
    492 }
    493 .seatreg-tabs-content .overview-middle-box {
    494   float: left;
    495   margin-right: 60px;
    496 }
    497 .seatreg-tabs-content .overview-middle-box-stat {
    498   font-size: 38px;
    499 }
    500 .seatreg-tabs-content .overview-last-box {
    501   margin-right: 0;
    502 }
    503 .seatreg-tabs-content .reg-overview-bottom {
    504   background-color: #404040;
    505   padding: 20px;
    506   clear: both;
    507   margin-top: 20px;
    508 }
    509 .seatreg-tabs-content .reg-link {
    510   display: inline-block;
    511   width: 500px;
    512   background-color: #fff;
    513   padding: 10px;
    514   text-decoration: none;
    515   color: #000;
    516   margin-bottom: 20px;
    517 }
    518 .seatreg-tabs-content .ov-bottom-h {
    519   color: #fff;
    520   font-size: 18px;
    521   padding: 0;
    522   margin-top: 0;
    523   margin-bottom: 20px;
    524 }
    525 .seatreg-tabs-content .ov-bottom-h-2 {
    526   color: #fff;
    527   font-size: 14px;
    528   padding: 0;
    529   margin-top: 0;
    530   margin-bottom: 0;
    531   cursor: pointer;
    532   padding-left: 10px;
    533 }
    534 .seatreg-tabs-content .ov-bottom-h-3 {
    535   color: #fff;
    536   font-size: 14px;
    537   padding: 0;
    538   margin-top: 0;
    539   margin-bottom: 0;
    540   cursor: pointer;
    541   padding-left: 10px;
    542 }
    543 
    544 .seatreg-tabs-content .ov-bottom-h-2:hover,
    545 .seatreg-tabs-content .ov-bottom-h-3:hover {
    546   color: #fff;
    547   text-decoration: underline;
    548 }
    549 
    550 .seatreg-tabs-content .copy-link-btn {
    551   display: inline-block;
    552   background-color: #fff;
    553   padding: 10px;
    554   font-weight: 600;
    555 }
    556 
    557 .seatreg-tabs-content .overview-middle-box-stat {
    558   color: orange;
    559   font-size: 36px;
    560 }
    561 .seatreg-tabs-content .stats-doughnut {
    562   margin-left: 40px;
    563 }
    564 .seatreg-tabs-content .stats-doughnut-legend {
    565   display: inline-block;
    566   vertical-align: top;
    567   margin-left: 20px;
    568   min-width: 160px;
    569 }
    570 .seatreg-tabs-content .legend-block {
    571   margin-top: 10px;
    572 }
    573 .seatreg-tabs-content .doughnut-legend {
    574   width: 16px;
    575   height: 16px;
    576   display: inline-block;
    577   border-radius: 50%;
    578   margin-right: 12px;
    579   vertical-align: bottom;
    580 }
    581 .seatreg-tabs-content .legend-block-percent {
    582   float: right;
    583 }
    584 .seatreg-tabs-content .reg-overview-top-date {
    585   float: right;
    586   line-height: 50px;
    587 }
    588 
    589488/*registrations manager*/
    590489.seatreg-tabs-content .tab_container {
    … …  
    616515}
    617516
    618 .seatreg-tabs-content .time-block {
    619   margin-bottom: 6px;
    620   margin-left: 10px;
    621 }
    622 
    623517.seatreg-tabs-content .registration-manager-labels {
    624518  padding: 16px;
    … …  
    634528  overflow: hidden;
    635529}
     530
    636531.seatreg-tabs-content .seat-nr-box {
    637532  width: 60px;
    638533}
     534
    639535.seatreg-tabs-content .seat-id-box {
    640536  margin-right: 30px;
    641537}
     538
    642539.seatreg-tabs-content .seat-room-box {
    643540  width: 140px;
    … …  
    657554  vertical-align: middle;
    658555}
     556
    659557.seatreg-tabs-content .payment-status-box {
    660558  min-width: 130px;
    … …  
    662560  margin-right: 40px;
    663561}
     562
    664563.seatreg-tabs-content .border-box {
    665564  -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    … …  
    667566  box-sizing: border-box; /* Opera/IE 8+ */
    668567}
     568
    669569.seatreg-tabs-content .seat-date-box {
    670570  width: 140px;
    671571  text-align: center;
    672572}
     573
    673574.seatreg-tabs-content .action-select {
    674575  float: right;
    675576}
     577
    676578.seatreg-tabs-content .action-select label {
    677579  margin-left: 10px;
    … …  
    683585  margin-right: 16px;
    684586}
     587
    685588.seatreg-tabs-content .differentBgColor {
    686589  background-color: #f2f2f2;
    … …  
    690593  display: inline-block;
    691594}
     595
    692596.seatreg-tabs-content .reg-seat-item .booking-id-box {
    693597  min-width: 340px;
    694598}
     599
    695600.seatreg-tabs-content .manager-box-link:hover {
    696601  cursor: pointer;
    697602  text-decoration: underline;
    698603}
    699 .seatreg-tabs-content #existing-regs {
    700   position: relative;
    701 }
    702604
    703605.seatreg-tabs-content .seat-date-label {
    704606  margin-right: 60px;
    705607}
     608
    706609.seatreg-tabs-content .reg-name {
    707610  font-size: 30px;
    … …  
    751654  text-decoration: underline;
    752655}
     656
    753657.seatreg-tabs-content .action-label {
    754658  cursor: pointer;
    … …  
    793697  color: red;
    794698}
     699
    795700.seatreg-delete-registration-form .delete-registration-btn:hover {
    796701  box-shadow: 1px 1px 10px 0px rgba(204, 204, 204, 0.52);
    … …  
    812717  border: 0;
    813718}
     719
    814720.seatreg-tabs-content .del-reg {
    815721  margin: 0;
    … …  
    824730  margin-top: 20px;
    825731}
     732
    826733.seatreg-tabs-content .del-reg:hover {
    827734  text-decoration: underline;
    828735  color: red;
    829736}
     737
    830738.seatreg-tabs-content .del-reg:focus {
    831739  outline: none;
    … …  
    841749  cursor: pointer;
    842750}
     751
    843752.seatreg-tabs-content .btn-style:hover {
    844753  text-decoration: underline;
    845754}
     755
    846756.seatreg-tabs-content .btn-style-active {
    847757  background-color: #fff;
    … …  
    855765  background-position: -3px -336px;
    856766}
     767
    857768.seatreg-tabs-content .a-stats-btn {
    858769  border-bottom: 1px solid #e1e5e7;
    859770}
     771
    860772.seatreg-tabs-content .a-manage-btn {
    861773  border-bottom: 1px solid #e1e5e7;
    862774}
     775
    863776.seatreg-tabs-content .a-manage-btn .f-pic {
    864777  float: left;
    865778  background-position: -52px -335px;
    866779}
     780
    867781.seatreg-tabs-content .adr-btn {
    868782  margin: 4px;
    … …  
    872786  line-height: 42px;
    873787}
     788
    874789.seatreg-tabs-content .adr-btn .f-pic {
    875790  float: left;
    876791  background-position: -105px -334px;
    877792}
     793
    878794.seatreg-tabs-content .a-opt-btn {
    879795  margin: 4px;
    … …  
    883799  line-height: 42px;
    884800}
     801
    885802.seatreg-tabs-content .option-box {
    886803  margin-top: 20px;
    … …  
    888805  border-bottom: 1px solid black;
    889806}
     807
    890808.seatreg-tabs-content .setting-box {
    891809  width: 98%;
    … …  
    894812  border-top: 1px solid black;
    895813}
     814
    896815.seatreg-tabs-content .a-opt-btn .f-pic {
    897816  float: left;
    … …  
    902821  text-align: center;
    903822}
     823
    904824.seatreg-tabs-content .del-reg-form:active,
    905825.seatreg-tabs-content .del-reg-form:focus {
    … …  
    915835  border-bottom: 1px solid #e1e5e7;
    916836}
     837
    917838.seatreg-tabs-content .info-box {
    918839  margin-bottom: 20px;
    … …  
    933854  vertical-align: middle;
    934855}
     856
    935857.seatreg-tabs-content .reg-status-box {
    936858}
     859
    937860.seatreg-tabs-content .custom-container {
    938861  display: flex;
    … …  
    986909  cursor: pointer;
    987910}
     911
    988912.seatreg-tabs-content .custom-container-move:hover {
    989913  background-color: #ccc;
    … …  
    997921  margin-left: 24px;
    998922}
     923
    999924.seatreg-tabs-content .payment-configuration {
    1000925  margin-top: 12px;
    … …  
    1039964  margin-left: 6px;
    1040965}
     966
    1041967.seatreg-tabs-content .cust-field-create {
    1042968  margin-top: 10px;
    1043969  margin-left: 24px;
    1044970}
     971
    1045972.seatreg-tabs-content .select-radio-create {
    1046973  margin-bottom: 12px;
    1047974}
     975
    1048976.seatreg-tabs-content .seatreg-settings-form input[type="text"],
    1049977.seatreg-tabs-content .seatreg-settings-form input[type="number"] {
    … …  
    1051979  font-size: 14px;
    1052980}
     981
    1053982.seatreg-tabs-content .seatreg-settings-form textarea {
    1054983  font-size: 14px;
    1055984}
     985
    1056986.seatreg-tabs-content .cust-field-create label {
    1057987  font-size: 14px;
    … …  
    1061991  margin-bottom: 0.5rem;
    1062992}
     993
    1063994.seatreg-tabs-content .select-option {
    1064995  margin-bottom: 6px;
    … …  
    10691000  width: 140px;
    10701001}
     1002
    10711003.seatreg-tabs-content .custom-field-select {
    10721004  margin-right: 10px;
    10731005}
     1006
    10741007.seatreg-tabs-content .manager-search-wrap {
    10751008  width: 200px;
    … …  
    10771010  float: right;
    10781011}
     1012
    10791013.seatreg-tabs-content .manager-search {
    10801014  border-color: #ccc;
    … …  
    10831017  min-height: calc(1.5rem + .75rem + 2px);
    10841018}
     1019
    10851020.seatreg-tabs-content .manager-search:focus {
    10861021  box-shadow: none;
    … …  
    11071042  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
    11081043}
     1044
    11091045.seatreg-tabs-content .option-label {
    11101046  font-size: 16px;
    11111047}
     1048
    11121049.seatreg-tabs-content .l-text {
    11131050  margin-right: 10px;
    … …  
    11171054.seatreg-tabs-content .option-btn {
    11181055}
     1056
    11191057.seatreg-tabs-content .edit-btn {
    11201058  cursor: pointer;
    … …  
    11291067.seatreg-tabs-content .admin-btn-from {
    11301068  border-bottom: 1px solid #e1e5e7;
    1131 }
    1132 
    1133 .seatreg-tabs-content .room-list-item[data-active="true"] {
    1134   color: orange;
    11351069}
    11361070
    … …  
    11471081  font-size: 14px;
    11481082}
     1083
    11491084.seatreg-map-popup-btn,
    11501085.seatreg-delete-btn {
    11511086  padding: 0;
    11521087}
     1088
    11531089.seatreg_page_seatreg-management
    11541090  .booking-status-check-wrap
    … …  
    11891125}
    11901126
    1191 @media screen and (max-width: 1199px) {
    1192   .seatreg-tabs-content #my-regs {
     1127@media screen and (max-width: 1199px) {  .seatreg-tabs-content #my-regs {
    11931128    width: 970px;
    11941129    padding: 0 15px;
    11951130  }
     1131
    11961132  .seatreg-tabs-content .admin-right-side {
    11971133    width: 700px;
    11981134  }
     1135
    11991136  .seatreg-tabs-content .admin-right-side {
    12001137    margin-right: 5px;
    12011138  }
    1202   .seatreg-tabs-content .reg-overview-middle {
    1203     width: 440px;
    1204   }
    1205   .seatreg-tabs-content .overview-middle-box {
    1206     margin-right: 30px;
    1207   }
     1139
    12081140  .seatreg-tabs-content .action-select {
    12091141    margin-top: 10px;
    … …  
    12111143    float: right;
    12121144  }
     1145
    12131146  .seatreg-tabs-content .bg-color {
    12141147    padding-top: 80px;
    12151148    background-color: #f2f2f2;
    12161149  }
    1217 }
    1218 @media screen and (max-width: 800px) {
    1219   .seatreg-tabs-content .manager-box {
     1150
     1151}
     1152
     1153@media screen and (max-width: 800px) {  .seatreg-tabs-content .manager-box {
    12201154    display: block;
    12211155    text-align: left;
    12221156  }
     1157
    12231158  .seatreg-tabs-content .action-select {
    12241159    margin-top: 0;
    12251160  }
     1161
    12261162  .seatreg-tabs-content .file-type-link {
    12271163    position: absolute;
    … …  
    12291165    margin: 0;
    12301166  }
     1167
    12311168  .seatreg-tabs-content .pdf-link {
    12321169    right: 0;
    12331170  }
     1171
    12341172  .seatreg-tabs-content .text-link {
    12351173    right: 150px;
    12361174  }
     1175
    12371176  .seatreg-tabs-content .xlsx-link {
    12381177    right: 70px;
    12391178  }
     1179
    12401180  .seatreg-tabs-content .manager-search-wrap {
    12411181    margin-top: 40px;
    12421182  }
     1183
    12431184  .seatreg-tabs-content .action-select {
    12441185    float: none;
    … …  
    12471188    margin-top: 10px;
    12481189  }
    1249 }
    1250 
    1251 @media screen and (max-width: 992px) {
    1252   .seatreg-tabs-content .reg-section-buttons {
     1190
     1191}
     1192
     1193@media screen and (max-width: 992px) {  .seatreg-tabs-content .reg-section-buttons {
    12531194    width: 20%;
    1254   }
    1255   .seatreg-tabs-content .reg-overview-middle-wrap {
    1256     display: block;
    12571195  }
    12581196
    … …  
    12611199  }
    12621200
    1263   .seatreg-tabs-content .reg-overview-aside {
    1264     width: 40%;
    1265     min-height: none;
    1266     max-height: none;
    1267   }
    1268 
    12691201  .seatreg-tabs-content .admin-right-side {
    12701202    width: 76%;
    1271   }
    1272 
    1273   .seatreg-tabs-content .reg-overview {
    1274     width: 100%;
    12751203  }
    12761204
    … …  
    12791207    margin: 0;
    12801208  }
    1281   .seatreg-tabs-content .reg-overview-aside {
    1282     float: none;
    1283     width: 100%;
    1284     max-height: none;
    1285     min-height: 0;
    1286     text-align: center;
    1287     margin-bottom: 0;
    1288     padding-right: 0;
    1289   }
    1290 
    1291   .seatreg-tabs-content .room-list-item {
    1292     display: inline-block;
    1293   }
    1294   .seatreg-tabs-content .reg-overview-middle {
    1295     float: none;
    1296     overflow: hidden;
    1297     width: 100%;
    1298     padding: 20px 20px 10px 20px;
    1299 
    1300     margin: 0px;
    1301     text-align: center;
    1302   }
    1303   .seatreg-tabs-content .reg-overview-top-date {
    1304     float: none;
    1305     clear: both;
    1306     text-align: center;
    1307     margin-top: 10px;
    1308   }
    1309   .seatreg-tabs-content .reg-overview-top-bron-notify {
    1310     float: right;
    1311     height: 30px;
    1312     margin-bottom: 10px;
    1313     margin-top: 10px;
    1314   }
    1315   .seatreg-tabs-content .reg-overview-top-bron-notify,
    1316   .seatreg-tabs-content .reg-overview-top-header,
    1317   .seatreg-tabs-content .reg-overview-top-date {
    1318     line-height: 20px;
    1319   }
    1320   .seatreg-tabs-content .time-block {
    1321     display: inline-block;
    1322     margin-bottom: 4px;
    1323   }
    1324   .seatreg-tabs-content .reg-link {
    1325     width: 100%;
    1326     word-wrap: break-word;
    1327     word-break: break-all;
    1328   }
    1329   .seatreg-tabs-content .reg-overview-top-header {
    1330     float: none;
    1331     text-align: center;
    1332     word-wrap: break-word;
    1333 
    1334     margin-top: 20px;
    1335   }
    1336   .seatreg-tabs-content .overview-middle-box {
    1337     margin-right: 10px;
    1338     display: inline-block;
    1339     float: none;
    1340     margin: 0 4px;
    1341   }
    1342   .seatreg-tabs-content .room-list-item {
    1343     display: inline-block;
    1344     margin-right: 20px;
    1345   }
     1209
    13461210  .seatreg-tabs-content #alertify {
    13471211    top: 30%;
    13481212  }
    13491213
    1350   .seatreg-tabs-content .reg-overview-donuts {
    1351     display: block;
    1352     width: 100%;
    1353     margin: 0;
    1354     text-align: center;
    1355     float: none;
    1356     padding: 0;
    1357   }
    1358   .seatreg-tabs-content .reg-overview-top-bron-notify {
    1359     float: none;
    1360     text-align: center;
    1361   }
    1362   .seatreg-tabs-content .reg-overview-top {
    1363     padding-top: 6px;
    1364     padding-bottom: 0px;
    1365     margin-bottom: 10px;
    1366   }
    1367   .seatreg-tabs-content .reg-overview-bottom {
    1368     clear: both;
    1369     margin-top: 20px;
    1370   }
    1371 
    1372   .seatreg-tabs-content .stats-doughnut {
    1373     margin: 0;
    1374   }
    1375   .seatreg-tabs-content .legend-block {
    1376     text-align: left;
    1377   }
    1378   .seatreg-tabs-content .stats-doughnut-legend {
    1379     margin-left: 0;
    1380   }
    1381 }
    1382 
    1383 @media screen and (max-width: 776px) {
    1384   .seatreg-tabs-content .reg-section-buttons {
     1214}
     1215
     1216@media screen and (max-width: 776px) {  .seatreg-tabs-content .reg-section-buttons {
    13851217    width: 25%;
    13861218  }
    … …  
    13931225    margin-bottom: 4px;
    13941226  }
     1227
    13951228  .seatreg-tabs-content .account-status {
    13961229    margin-bottom: 0;
    13971230  }
     1231
    13981232  .seatreg-tabs-content .first-reg-section .tab_container:before {
    13991233    margin-top: -300px;
    … …  
    14051239    height: 310px;
    14061240  }
     1241
    14071242  .seatreg-tabs-content .tab a {
    14081243    padding: 0px 0px;
    14091244  }
    1410 }
    1411 
    1412 @media screen and (max-width: 900px) {
     1245
     1246}
     1247
     1248@media screen and (max-width: 900px) {  .seatreg-tabs-content .first-reg-section .tab_container:before {
     1249    margin-top: -330px;
     1250    height: 330px;
     1251  }
     1252
     1253  .seatreg-tabs-content .tab_container:before {
     1254    margin-top: -250px;
     1255    height: 250px;
     1256  }
     1257
     1258}
     1259
     1260@media screen and (max-width: 500px) {  .seatreg-tabs-content .bg-color {
     1261    padding-top: 100px;
     1262  }
     1263
     1264  .seatreg-tabs-content .reg-section-buttons {
     1265    font-size: 12px;
     1266  }
     1267
     1268  .seatreg-tabs-content .bg-color {
     1269    background-color: #f2f2f2;
     1270  }
     1271
    14131272  .seatreg-tabs-content .first-reg-section .tab_container:before {
    14141273    margin-top: -330px;
    … …  
    14171276
    14181277  .seatreg-tabs-content .tab_container:before {
    1419     margin-top: -250px;
    1420     height: 250px;
    1421   }
    1422 }
    1423 @media screen and (max-width: 500px) {
    1424   .seatreg-tabs-content .bg-color {
    1425     padding-top: 100px;
    1426   }
    1427   .seatreg-tabs-content .reg-section-buttons {
    1428     font-size: 12px;
    1429   }
    1430   .seatreg-tabs-content .bg-color {
    1431     background-color: #f2f2f2;
    1432   }
    1433 
    1434   .seatreg-tabs-content .first-reg-section .tab_container:before {
    14351278    margin-top: -330px;
    14361279    height: 330px;
    14371280  }
    14381281
    1439   .seatreg-tabs-content .tab_container:before {
    1440     margin-top: -330px;
    1441     height: 330px;
    1442   }
    14431282  .seatreg-tabs-content .custom-container input[type="text"] {
    14441283    width: 60px;
    14451284  }
     1285
    14461286}
    14471287
    … …  
    14581298    color: #04357d;
    14591299  }
     1300
    14601301  .calendar-date-chip-remove {
    14611302    margin-left: 6px;
    … …  
    14731314      color: #c00;
    14741315    }
    1475   }
    1476 }
     1316
     1317  }
     1318}
  • seatreg/trunk/css/seatreg_admin.min.css

    r3680221 r3693621  
    1 .seatreg-tabs-content .add-modal .bottom-action .seat-operations .seat-operation:hover,.seatreg-tabs-content .management-header .management-extra-actions .add-booking:hover span,.seatreg-tabs-content .management-header .management-extra-actions .import-bookings:hover span,.seatreg-tabs-content .seat-id-modal .seat-id-grid .grid-title,.seatreg-wp-admin .nav-tab.nav-tab-active{text-decoration:underline}.seatreg-tabs-content .edit-modal h5{margin-bottom:0}.seatreg-tabs-content .edit-modal .edit-modal-input-wrap,.seatreg-tabs-content .edit-modal .modal-custom{margin-bottom:12px}.seatreg-tabs-content .add-modal h5{margin-bottom:.5rem}.seatreg-tabs-content .add-modal .add-modal-input-wrap{margin-bottom:12px}.seatreg-tabs-content .add-modal .add-modal-input-wrap .seat-id-search{vertical-align:middle;padding-top:20px;margin-left:4px;cursor:pointer}.seatreg-tabs-content .add-modal .modal-custom{margin-bottom:12px}.seatreg-tabs-content .add-modal .add-modal-calendar-date{display:flex;justify-content:center;align-items:center}.seatreg-tabs-content .add-modal .add-modal-calendar-date .fa{margin-right:8px}.seatreg-tabs-content .add-modal .modal-body-items{display:flex;overflow-x:auto}.seatreg-tabs-content .add-modal .modal-body-items .modal-body-item:not(:last-child){margin-right:24px}.seatreg-tabs-content .add-modal .modal-body-items .modal-body-item .input-error{color:red}.seatreg-tabs-content .add-modal .bottom-action{margin-top:24px}.seatreg-tabs-content .add-modal .bottom-action .seat-operations{display:flex;justify-content:center;margin-bottom:12px}.seatreg-tabs-content .add-modal .bottom-action .seat-operations .seat-operation{cursor:pointer}.seatreg-tabs-content .add-modal .bottom-action .seat-operations .seat-operation:first-child{margin-right:12px}.seatreg-tabs-content .add-modal .bottom-action .fa-plus-circle{color:#61B329}.seatreg-tabs-content .add-modal .bottom-action .bottom-action-item__input-error,.seatreg-tabs-content .add-modal .bottom-action .fa-minus-circle{color:red}.seatreg-tabs-content .add-modal .bottom-action .bottom-action-item{cursor:pointer;text-align:center;margin-bottom:12px}.seatreg-tabs-content .add-modal .bottom-action .bottom-action-item__title{font-weight:700}.seatreg-wp-admin .activity-modal__loading{text-align:center}.seatreg-wp-admin .activity-modal__logs{display:grid;grid-template-columns:200px 1fr}#seatreg-booking-manager .bookings-file-modal .date-info{display:flex;justify-content:center;align-items:center;margin-bottom:12px}#seatreg-booking-manager .bookings-file-modal .date-info .fa{margin-right:8px}#seatreg-booking-manager .bookings-file-modal input{margin-left:8px}#seatreg-booking-manager .bookings-file-modal .fa-plus-circle{color:#61B329}#seatreg-booking-manager .bookings-file-modal .form-fields{margin-bottom:12px}#seatreg-booking-manager .bookings-file-modal .custom-filtering{cursor:pointer}#seatreg-booking-manager .bookings-file-modal .custom-filtering-selection{display:none;margin-top:12px}.seatreg-tabs-content .seat-id-modal h5{margin-top:8px}.seatreg-tabs-content .seat-id-modal .seat-id-grid{display:grid;row-gap:8px;grid-template-columns:auto 1fr 1fr;margin-left:40px;grid-column-gap:30px}.seatreg-tabs-content .seat-id-modal .seat-id-grid .grid-title{margin-bottom:8px}#import-bookings-modal .import-booking-modal-error{color:#E0635D;font-size:14px;margin-top:8px}#import-bookings-modal .import-booking-modal-loading{display:flex;flex-direction:column;align-items:center}#import-bookings-modal .import-booking-modal-loading img{margin-bottom:8px}#seatreg-booking-manager .import-bookings-finalization-modal__body{max-height:70vh;overflow-y:auto}#seatreg-booking-manager .import-bookings-finalization-modal__booking{display:flex;align-items:center;border:1px solid #ccc;padding:8px 12px;gap:6px;margin-bottom:8px}#seatreg-booking-manager .import-bookings-finalization-modal__booking--invalid{border-color:#d10516}#seatreg-booking-manager .import-bookings-finalization-modal__trash-icon,#seatreg-booking-manager .import-bookings-finalization-modal__warning-icon{margin-left:auto;color:red;cursor:pointer}#seatreg-booking-manager .import-bookings-finalization-modal__popup{max-width:400px}#seatreg-booking-manager .import-bookings-finalization-modal .warn-text{color:#d10516;font-weight:700}.seatreg-wp-admin .shortcode-modal .shortcode-instructions{margin-top:12px;margin-bottom:0}.seatreg-tabs-content .ajax_loader{position:fixed;top:50%;left:50%;margin-left:-32px;margin-top:-32px;z-index:9999}@media screen and (max-width:992px){.seatreg-tabs-content .ajax_loader{top:20%;left:50%;margin-left:-32px;margin-top:-32px}}.seatreg-tabs-content .management-header{position:relative;display:flex;flex-wrap:wrap;justify-content:space-between;background-color:#F2F2F2;text-transform:uppercase;font-size:20px;min-height:42px;padding:6px 6px 16px}.seatreg-tabs-content .management-header>div{min-width:150px}.seatreg-tabs-content .management-header .pending-bookings-count{color:#E0635D}.seatreg-tabs-content .management-header .management-extra-actions{display:flex;gap:12px;text-transform:none}.seatreg-tabs-content .management-header .management-extra-actions .add-booking{cursor:pointer}.seatreg-tabs-content .management-header .management-extra-actions .add-booking .fa-plus-circle{color:#61B329}.seatreg-tabs-content .management-header .management-extra-actions .import-bookings{cursor:pointer}.seatreg-tabs-content .management-header .management-extra-actions .import-bookings .fa{color:#4ea8f0}.seatreg-tabs-content .management-header .booking-manager-calendar-wrap{width:100%;display:flex;justify-content:center;align-items:center;margin-bottom:12px}.seatreg-tabs-content .management-header .booking-manager-calendar-wrap label{margin-bottom:0}.seatreg-tabs-content .management-header .booking-manager-calendar-wrap input{text-align:center;margin-left:12px;width:170px}.reg-more-items{display:flex;flex-wrap:wrap}.reg-more-items__item{padding:24px;border:1px solid #ccc;border-radius:3px;margin-right:12px;cursor:pointer}.reg-more-items__item:hover{box-shadow:1px 1px 10px 0 rgba(204,204,204,.52)}.reg-more-items__item--delete-form{padding:0}#seatreg-booking-manager .custom-fields .custom-field{display:flex;align-items:center;margin-bottom:8px}#seatreg-booking-manager .custom-fields .custom-field input,#seatreg-booking-manager .custom-fields .custom-field label{margin-bottom:0}#seatreg-booking-manager .custom-fields .custom-field .fa{cursor:pointer;margin-left:8px}#seatreg-settings-form #public-api-tokens{margin-left:24px;margin-bottom:12px}#seatreg-settings-form #public-api-tokens .token-box{display:flex;align-items:center;border:1px solid #ccc;padding:12px;border-radius:4px;column-gap:6px;margin-bottom:12px}#seatreg-settings-form #public-api-tokens .token-box .token-actions{margin-left:auto}#seatreg-settings-form #custom-payments,#seatreg-settings-form .coupon-box__actions,#seatreg-settings-form .coupon-create,#seatreg-settings-form .existing-coupons{margin-left:24px}#seatreg-settings-form #public-api-tokens .token-box .token-actions .remove-token{color:red;cursor:pointer}#seatreg-settings-form #custom-payments .custom-payment{border:1px solid #ccc;padding:12px;border-radius:4px;display:grid;grid-template-columns:auto 1fr;column-gap:24px;row-gap:12px;margin-bottom:24px}#seatreg-settings-form #custom-payments .custom-payment__controls{text-align:center;grid-column:span 2}#seatreg-settings-form .custom-payment-icon-upload{display:flex}#seatreg-settings-form .custom-payment-icon-upload__error{color:red}#seatreg-settings-form .custom-payment-icon-upload__loading{margin-right:8px;display:none}#seatreg-settings-form .current-custom-payment-icon{display:flex;align-items:center}#seatreg-settings-form .current-custom-payment-icon__loading,.settings-tab-panel{display:none}#seatreg-settings-form .current-custom-payment-icon__img{height:74px;margin-right:12px}#seatreg-settings-form .current-custom-payment-icon__delete{cursor:pointer;color:red}#seatreg-booking-manager .approved-booking-email-text{margin-top:12px;display:flex;flex-direction:column;align-items:start;gap:6px}#seatreg-booking-manager .approved-booking-email-text__input-wrapper{display:flex;align-items:center;gap:6px}#seatreg-booking-manager .approved-booking-email-text__warning{color:red}#seatreg-settings-form .existing-coupons{margin-bottom:24px}#seatreg-settings-form .new-coupon{display:flex;align-items:center;gap:8px}#seatreg-settings-form .new-coupon input[type=text]{width:120px}#seatreg-settings-form .new-coupon input[type=number]{width:80px}.seatreg-flower-container,.seatreg-flower-droplet{height:var(--flower-size);width:var(--flower-size);position:absolute}#seatreg-settings-form .new-coupon__label{font-size:14px;margin-bottom:0}#seatreg-settings-form .coupon-box{display:flex;align-items:center;margin-bottom:12px}#seatreg-settings-form .coupon-box__label{margin-right:8px;font-size:14px}#seatreg-settings-form .coupon-box__value{font-weight:600;min-width:80px}.seatreg-wp-admin .companion-app-form .submit{margin-top:8px}@keyframes shake{0%{transform:translate(1px,1px) rotate(0)}10%{transform:translate(-1px,-2px) rotate(-1deg)}20%{transform:translate(-3px,0) rotate(1deg)}30%{transform:translate(3px,2px) rotate(0)}40%{transform:translate(1px,-1px) rotate(1deg)}50%{transform:translate(-1px,2px) rotate(-1deg)}60%{transform:translate(-3px,1px) rotate(0)}100%,70%{transform:translate(0,0) rotate(0)}}.seatreg-flower-container{--flower-size:12px;--flower-delay:0s;--flower-opacity:0.2}.seatreg-flower-droplet{border-radius:5px 90%;border-style:solid;border-width:1px;top:var(--flower-size);left:var(--flower-size);transform-origin:left top;opacity:0}.seatreg-flower-droplet-1{background:#428bca;animation:spin1 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + 0s)}.seatreg-flower-droplet-2{background:#2271b1;animation:spin2 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .05s)}.seatreg-flower-droplet-3{background:#428bca;animation:spin3 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .1s)}.seatreg-flower-droplet-4{background:#2271b1;animation:spin4 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .15s)}.seatreg-flower-droplet-5{background:#428bca;animation:spin5 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .2s)}.seatreg-flower-droplet-6{background:#2271b1;animation:spin6 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .25s)}.seatreg-flower-droplet-7{background:#428bca;animation:spin7 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .3s)}.seatreg-flower-droplet-8{background:#2271b1;animation:spin8 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .35s)}.seatreg-flower-droplet-9{background:#428bca;animation:spin9 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .4s)}.seatreg-flower-droplet-10{background:#2271b1;animation:spin10 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .45s)}@keyframes spin1{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(324deg) scale(1);transform:rotate(324deg) scale(1)}}@keyframes spin2{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(288deg) scale(1);transform:rotate(288deg) scale(1)}}@keyframes spin3{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(252deg) scale(1);transform:rotate(252deg) scale(1)}}@keyframes spin4{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(216deg) scale(1);transform:rotate(216deg) scale(1)}}@keyframes spin5{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(180deg) scale(1);transform:rotate(180deg) scale(1)}}@keyframes spin6{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(144deg) scale(1);transform:rotate(144deg) scale(1)}}@keyframes spin7{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(108deg) scale(1);transform:rotate(108deg) scale(1)}}@keyframes spin8{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(72deg) scale(1);transform:rotate(72deg) scale(1)}}@keyframes spin9{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(36deg) scale(1);transform:rotate(36deg) scale(1)}}@keyframes spin10{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(0) scale(1);transform:rotate(0) scale(1)}}.seatreg-wp-admin .seatreg-update-notice{position:absolute;left:15px;bottom:100%;margin-bottom:10px;font-size:13px}.seatreg-registrations{--seatreg-donate-rows:3;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-flow:row dense;gap:16px;margin-bottom:32px}.seatreg-registrations #create-registration-form,.seatreg-registrations .donate-wrap,.seatreg-registrations .your-registrations-header{grid-column:1/-1}.seatreg-registrations .donate-wrap{align-self:start}@media screen and (min-width:860px){.seatreg-registrations{grid-template-columns:repeat(3,minmax(0,1fr))}.seatreg-registrations #create-registration-form,.seatreg-registrations .seatreg-registrations-empty,.seatreg-registrations .your-registrations-header{grid-column:1/-3}.seatreg-registrations .donate-wrap{grid-row:1/span var(--seatreg-donate-rows);grid-column:-3/-1}}@media screen and (min-width:1250px){.seatreg-registrations{grid-template-columns:repeat(4,minmax(0,1fr))}}@media screen and (min-width:1600px){.seatreg-registrations{grid-template-columns:repeat(5,minmax(0,1fr))}}@media screen and (min-width:1900px){.seatreg-registrations{grid-template-columns:repeat(6,minmax(0,1fr))}}.seatreg-registrations-empty{grid-column:1/-1;margin-top:28px;padding:24px;border:1px dashed #c3c4c7;border-radius:4px;color:#646970}.seatreg-registration-card{display:flex;font-size:13px;flex-direction:column;row-gap:8px;padding:16px;background-color:#fff;border:1px solid #dcdcde;border-radius:4px}.seatreg-registration-card__head{display:flex;align-items:flex-start;justify-content:space-between;column-gap:8px}.seatreg-registration-card__status{display:flex;flex-shrink:0;align-items:center;column-gap:6px}.seatreg-registration-card__calendar-icon{color:#646970;font-size:14px}.seatreg-registration-card__title{margin:0;overflow-wrap:anywhere}.seatreg-registration-card__title .registration-name-link{color:#333;font-size:18px}.seatreg-registration-card__badge{flex-shrink:0;padding:4px 8px;color:#fff;font-size:12px;font-weight:600}.seatreg-registration-card__badge--open{background-color:#2e7d32}.seatreg-registration-card__badge--scheduled{background-color:#0073aa}.seatreg-registration-card__badge--closed{background-color:#8c8f94}.seatreg-registration-card__badge--ended{background-color:#50575e}.seatreg-registration-card__meta{color:#646970;font-size:13px}.seatreg-registration-card__actions{display:flex;flex-direction:column;align-items:flex-start;row-gap:4px;padding-top:4px}.seatreg-registration-card__actions .btn-link,.seatreg-registration-card__actions a{padding:0;color:#428bca;font-size:14px;text-align:left}.seatreg-registration-card__footer{display:flex;flex-direction:column;row-gap:8px;margin-top:auto;padding-top:12px;border-top:1px solid #c3c4c7}.seatreg-registration-card__footer-date{color:#646970;font-size:12px}.seatreg-registration-card__footer-date .fa{margin-right:4px}.seatreg-registration-card__footer-notice{color:#646970;font-size:13px;font-style:italic}.seatreg-registration-card__stats{display:flex;column-gap:8px}.seatreg-registration-card__stat{display:flex;flex:1;flex-direction:column;text-decoration:none}.seatreg-registration-card__stat:focus,.seatreg-registration-card__stat:hover{text-decoration:none}.seatreg-registration-card__stat:focus .seatreg-registration-card__stat-value,.seatreg-registration-card__stat:hover .seatreg-registration-card__stat-value{color:#428bca}.seatreg-registration-card__stat--highlight .seatreg-registration-card__stat-value{color:#b32d2e}.seatreg-registration-card__stat-value{color:#646970;font-size:18px;font-weight:600;line-height:1.2}.seatreg-registration-card__stat-label{color:#8c8f94;font-size:12px}@media screen and (max-width:782px){.seatreg-registrations{grid-template-columns:minmax(0,1fr)}}html{font-size:100%}.index-icon{margin-right:10px}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:active,.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.seatreg-wp-admin .btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.seatreg-wp-admin .btn-primary:active,.seatreg-wp-admin .btn-primary:hover{background-color:#3276b1;border-color:#285e8e}.seatreg-wp-admin input[type=checkbox]:focus{outline:0}.seatreg-wp-admin{font-family:"Open Sans",sans-serif}.seatreg-wp-admin .home-content{display:flow-root;position:relative}.seatreg-wp-admin .jumbotron{background-image:url(../img/chairs_med.jpg);background-size:cover;margin-left:-20px;margin-bottom:42px}.seatreg-wp-admin .donate-wrap{max-width:100%;display:flex;flex-direction:column;padding:0 15px;align-items:center;text-align:center;row-gap:12px;position:relative}.seatreg-wp-admin .donate-wrap p{margin-bottom:.6rem}.seatreg-wp-admin .donate-wrap>img{margin-right:12px}.seatreg-wp-admin .donate-wrap .donate-paypal{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px}.seatreg-wp-admin .donate-wrap .donate-paypal p{margin:0}.seatreg-wp-admin .donate-wrap .donate-paypal form{display:flex;margin:0}.seatreg-wp-admin .donate-wrap .donate-img{cursor:pointer;transition:transform .15s ease,filter .15s ease;animation:shake 1s;animation-delay:1s;animation-iteration-count:10}.seatreg-wp-admin .donate-wrap .donate-img:focus-visible,.seatreg-wp-admin .donate-wrap .donate-img:hover{transform:scale(1.05);filter:brightness(1.08)}.seatreg-wp-admin .donate-wrap .buy-me-coffee-link img{width:120px}.seatreg-wp-admin .your-registrations-header{margin-top:28px;margin-bottom:24px}.seatreg-wp-admin .nav-tab:first-of-type{margin-left:0}.seatreg-wp-admin .nav-tab{background:#f2f2f2}.new-reg-title{margin-bottom:24px}.seatreg-wp-admin .jumbotron .main-heading{font-size:38px;font-weight:600}.seatreg-wp-admin .jumbotron .jumbotron-text{font-size:21px;font-weight:600}.seatreg-wp-admin .nav-tabs{margin-top:40px}.seatreg-tabs-content{background-color:#f2f2f2;padding:24px;border:1px solid #ccc;border-top:none;position:relative}.seatreg-tabs-content .etabs{margin:0;padding:0 0 6px;background-color:#f2f2f2}.seatreg-tabs-content .tab{display:inline-block;margin-right:2px;padding:6px;zoom:1;background:#fff}.seatreg-tabs-content .tab a{font-size:16px;line-height:2em;display:block;padding:0 30px;outline:0;text-decoration:none;color:#000}.seatreg-tabs-content .tab a:hover,.settings-tab:hover{text-decoration:underline}.seatreg-tabs-content .tab.active{background:#404040;position:relative}.seatreg-tabs-content .tab a.active{font-weight:700;color:#fff}.seatreg-tabs-content .tab-container .panel-container{overflow:hidden}.seatreg-tabs-content .form-group{margin-bottom:25px}.seatreg-settings-form .form-group{max-width:600px}.seatreg-settings-form .flow-summary-group{max-width:none}.settings-tabs{display:flex;flex-wrap:wrap;gap:10px;margin:16px 0 0;padding:0;background-color:#f2f2f2}.settings-tab{background:#fff;border:none;padding:6px 24px;cursor:pointer;font-size:16px;line-height:2em;color:#000}.settings-tab.settings-tab--active{background:#404040;font-weight:700;color:#fff}.settings-tab.settings-tab--active:hover{text-decoration:none}.settings-tab-panels{padding:32px 0 0;background:0 0}.settings-tab-panel.settings-tab-panel--active{display:block}.email-color-fields{display:grid;grid-template-columns:max-content max-content;align-items:center;gap:10px 16px;margin-top:12px}.email-logo-controls{display:flex;align-items:center;gap:12px;margin:12px 0;flex-wrap:wrap}#email-logo-preview,#page-logo-preview{max-height:60px;max-width:200px;border:1px solid #e2e8f0;border-radius:4px;padding:4px;background:#fff}.email-color-field{display:contents}.email-color-field label{font-size:13px;margin:0}.email-color-field input[type=color]{width:48px;height:32px;padding:0;border:1px solid #ccc;border-radius:4px;cursor:pointer}.email-color-field input[type=color]:disabled{opacity:.5;cursor:not-allowed}.seatreg-settings-form #seatreg-settings-submit{margin-top:20px}.booking-flow-details__summary{cursor:pointer;font-weight:700;font-size:14px;padding:4px 0;user-select:none;list-style:none;display:flex;align-items:center;color:#2271b1}.booking-flow-details__summary::-webkit-details-marker{display:none}.booking-flow-details__summary:hover{color:#135e96}.booking-flow-details__icon{margin-right:8px;transition:transform .15s ease}.booking-flow-details[open] .booking-flow-details__icon{transform:rotate(90deg)}.booking-flow-details__hint{font-weight:400;font-size:12px;color:#777;margin-left:8px}.booking-flow-details .help-block{margin-top:10px}#booking-flow-summary .flow-group{margin-bottom:12px}#booking-flow-summary .flow-group:last-child{margin-bottom:0}#booking-flow-summary .flow-group__title{font-weight:600;margin-bottom:4px}#booking-flow-summary .flow-group__list{margin:0;padding-left:20px;list-style:disc}#booking-flow-summary .flow-group__list li{margin-bottom:3px}#booking-flow-summary .flow-jump{margin-left:6px;font-size:12px;color:#2271b1;text-decoration:none}#booking-flow-summary .flow-jump:hover{color:#135e96}.flow-jump-highlight{animation:seatregFlowHighlight 1.6s ease;border-radius:4px}@keyframes seatregFlowHighlight{0%{background-color:#fff3b0}100%{background-color:transparent}}.seatreg-tabs-content #admin-wrapper{width:960px;margin:0 auto;font-family:"Open Sans",sans-serif}.seatreg-tabs-content #my-regs{width:1170px;margin:0 auto;padding:0 15px}.seatreg-tabs-content #server-response-text{font-size:20px}.seatreg-tabs-content .log-out-btn{display:block;float:right;text-decoration:none;width:150px;height:33px;line-height:33px;font-size:18px}.seatreg-tabs-content .log-out-btn .l-pic{float:left;background:url(sprites.png) -5px -388px no-repeat;width:32px;height:33px;padding-right:10px}.seatreg-tabs-content .reg-section{overflow:hidden;min-height:608px}.seatreg-tabs-content .reg-overview-middle-wrap{display:flex;flex-wrap:nowrap;align-items:center}.seatreg-tabs-content .reg-overview-top{padding-bottom:20px;overflow:hidden}.seatreg-tabs-content .overview-calendar-wrap{display:flex;justify-content:center;align-items:center;margin-bottom:20px}.seatreg-tabs-content .overview-calendar-wrap label{margin-bottom:0;text-transform:uppercase}.seatreg-tabs-content .overview-calendar-wrap input{text-align:center;margin-left:12px;width:170px}.seatreg-tabs-content .reg-overview-aside{width:220px;float:left;padding-right:20px;text-overflow:ellipsis;min-height:180px;margin-bottom:20px;position:relative;overflow:auto}.seatreg-tabs-content .room-list{list-style:none;margin:0;padding:0}.seatreg-tabs-content .room-list-active{color:#f47a37}.seatreg-tabs-content .room-list-item{margin-bottom:2px;font-size:18px}.seatreg-tabs-content .first-item{margin-bottom:6px;font-size:20px;text-transform:uppercase}.seatreg-tabs-content .room-list-item:hover{cursor:pointer;color:#f47a37}.seatreg-tabs-content .reg-overview-top-header{font-size:24px;font-weight:700;float:left;min-width:200px;height:50px;line-height:50px;margin-right:10px;display:none}.seatreg-tabs-content .reg-overview-top-header:first-letter{text-transform:capitalize}.seatreg-tabs-content .reg-overview-top-bron-notify{color:#ea6060;font-size:14px;float:left;height:50px;line-height:50px}.seatreg-tabs-content .reg-overview-middle{float:left;width:640px;margin-bottom:30px;margin-left:40px}.seatreg-tabs-content .overview-middle-box{float:left;margin-right:60px}.seatreg-tabs-content .overview-last-box{margin-right:0}.seatreg-tabs-content .reg-overview-bottom{background-color:#404040;padding:20px;clear:both;margin-top:20px}.seatreg-tabs-content .reg-link{display:inline-block;width:500px;background-color:#fff;padding:10px;text-decoration:none;color:#000;margin-bottom:20px}.seatreg-tabs-content .ov-bottom-h{color:#fff;font-size:18px;padding:0;margin-top:0;margin-bottom:20px}.seatreg-tabs-content .ov-bottom-h-2,.seatreg-tabs-content .ov-bottom-h-3{color:#fff;font-size:14px;padding:0 0 0 10px;margin-top:0;margin-bottom:0;cursor:pointer}.seatreg-tabs-content .ov-bottom-h-2:hover,.seatreg-tabs-content .ov-bottom-h-3:hover{color:#fff;text-decoration:underline}.seatreg-tabs-content .copy-link-btn{display:inline-block;background-color:#fff;padding:10px;font-weight:600}.seatreg-tabs-content .reg-seat-item,.seatreg-tabs-content .registration-manager-labels{border-bottom:3px solid #f0f0f0;padding:16px;background-color:#fff}.seatreg-tabs-content .overview-middle-box-stat{color:orange;font-size:36px}.seatreg-tabs-content .stats-doughnut{margin-left:40px}.seatreg-tabs-content .stats-doughnut-legend{display:inline-block;vertical-align:top;margin-left:20px;min-width:160px}.seatreg-tabs-content .legend-block{margin-top:10px}.seatreg-tabs-content .doughnut-legend{width:16px;height:16px;display:inline-block;border-radius:50%;margin-right:12px;vertical-align:bottom}.seatreg-tabs-content .legend-block-percent{float:right}.seatreg-tabs-content .reg-overview-top-date{float:right;line-height:50px}.seatreg-tabs-content .tab_container{overflow:visible!important}.seatreg-tabs-content .panel-container .tab_container{display:none}.seatreg-tabs-content .panel-container .tab_container.active{display:block}.seatreg-tabs-content .first-reg-section .tab_container:before{display:block;content:" ";margin-top:-240px;height:240px;visibility:hidden}.seatreg-tabs-content .tab_container:before{display:block;content:" ";margin-top:-170px;height:170px;visibility:hidden}.seatreg-tabs-content .time-block{margin-bottom:6px;margin-left:10px}.seatreg-tabs-content .reg-seat-item{font-size:14px;overflow:hidden}.seatreg-tabs-content .seat-nr-box{width:60px}.seatreg-tabs-content .seat-date-box,.seatreg-tabs-content .seat-name-box,.seatreg-tabs-content .seat-room-box{width:140px;text-align:center}.seatreg-tabs-content .seat-id-box{margin-right:30px}.seatreg-tabs-content .booking-status-box{margin-left:180px}.seatreg-tabs-content .seat-name-box{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;vertical-align:middle}.seatreg-tabs-content .payment-status-box{min-width:130px;text-align:center;margin-right:40px}.seatreg-tabs-content .border-box{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.seatreg-tabs-content .action-select{float:right}.seatreg-tabs-content .action-select label{margin-left:10px;display:inline-flex;align-items:center}.seatreg-tabs-content .show-more-info{margin-right:16px}.seatreg-tabs-content .differentBgColor{background-color:#f2f2f2}.seatreg-tabs-content .manager-box{display:inline-block}.seatreg-tabs-content .reg-seat-item .booking-id-box{min-width:340px}.seatreg-tabs-content .manager-box-link:hover{cursor:pointer;text-decoration:underline}.seatreg-tabs-content #existing-regs{position:relative}.seatreg-tabs-content .seat-date-label{margin-right:60px}.seatreg-tabs-content .reg-name{font-size:30px;word-wrap:break-word}.seatreg-tabs-content .account-status{text-align:right;margin-top:10px;margin-bottom:-50px;font-weight:600}.seatreg-tabs-content .more-info{display:none;padding-top:10px}.seatreg-tabs-content .action-control{background-color:#404040;text-align:center;width:100px;float:right;cursor:pointer;color:#fff;padding:4px 0;margin-top:24px}.seatreg-settings-form .checkbox label{font-size:14px}.seatreg-tabs-content .settings-heading{margin-top:0;margin-bottom:24px}.seatreg-tabs-content .action-select .bron-action,.seatreg-tabs-content .action-select .permanent-delete-action{margin-left:4px;cursor:pointer;margin-top:0}.seatreg-tabs-content .action-control:hover{text-decoration:underline}.seatreg-tabs-content .action-label{cursor:pointer}.seatreg-tabs-content .reg-section-buttons{width:160px;float:left}.seatreg-tabs-content .admin-right-side{width:900px;margin-right:5px;float:right;position:relative;background-color:#fff}.seatreg-tabs-content .notify-text{text-align:center;margin-top:24px;font-size:20px}.seatreg-tabs-content .action-select label{margin-bottom:0}.seatreg-delete-registration-form .delete-registration-btn,.seatreg-delete-registration-form .delete-registration-btn:active,.seatreg-delete-registration-form .delete-registration-btn:focus,.seatreg-delete-registration-form .delete-registration-btn:hover{padding:24px;min-height:auto;line-height:normal;border:1px solid #ccc;box-shadow:none;background:#fff;font-size:16px;color:red}.seatreg-delete-registration-form .delete-registration-btn:hover{box-shadow:1px 1px 10px 0 rgba(204,204,204,.52)}.change-name-wrap{margin-bottom:8px}.seatreg-tabs-content .f-pic{width:41px;height:41px;background:url(sprites.png) no-repeat}.seatreg-tabs-content .a-build-btn{margin:0;padding:0;border:0}.seatreg-tabs-content .del-reg{margin:20px 0 0;padding:0;border:0;display:block;background-color:#404040;color:#fff;height:40px;width:160px}.seatreg-tabs-content .del-reg:hover{text-decoration:underline;color:red}.seatreg-tabs-content .del-reg:focus{outline:0}.seatreg-tabs-content .btn-style{background-color:#404040;color:#fff;width:160px;height:40px;line-height:40px;text-align:center;cursor:pointer}.seatreg-tabs-content .a-opt-btn,.seatreg-tabs-content .adr-btn{margin:4px;padding:4px;width:140px;height:54px;line-height:42px}.seatreg-tabs-content .btn-style:hover{text-decoration:underline}.seatreg-tabs-content .btn-style-active{background-color:#fff;color:#000;text-transform:uppercase;font-weight:700}.seatreg-tabs-content .a-build-btn .f-pic{float:left;background-position:-3px -336px}.seatreg-tabs-content .a-manage-btn,.seatreg-tabs-content .a-stats-btn{border-bottom:1px solid #e1e5e7}.seatreg-tabs-content .a-manage-btn .f-pic{float:left;background-position:-52px -335px}.seatreg-tabs-content .adr-btn .f-pic{float:left;background-position:-105px -334px}.seatreg-tabs-content .option-box{margin-top:20px;padding-bottom:20px;border-bottom:1px solid #000}.seatreg-tabs-content .setting-box{width:98%;margin:0 auto;padding:0 1%;border-top:1px solid #000}.seatreg-tabs-content .a-opt-btn .f-pic{float:left;background-position:-154px -332px}.seatreg-tabs-content .del-reg-form{text-align:center}.seatreg-tabs-content .del-reg-form:active,.seatreg-tabs-content .del-reg-form:focus{border:none}.seatreg-tabs-content .del-reg .f-pic{float:left;background-position:-203px -331px}.seatreg-tabs-content .a-options-btn{border-bottom:1px solid #e1e5e7}.seatreg-tabs-content .info-box{margin-bottom:20px}.seatreg-tabs-content .option-checkbox{width:20px;height:20px;vertical-align:middle;margin:0!important}.seatreg-tabs-content .select-radio-create{display:none}.seatreg-tabs-content .remove-sel-item{vertical-align:middle}.seatreg-tabs-content .custom-container{display:flex;align-items:center;flex-wrap:nowrap;column-gap:6px;margin-bottom:4px;margin-left:24px;border:1px solid #ccc;border-radius:4px;padding:12px 18px}.seatreg-tabs-content .custom-container label{margin-bottom:0;display:flex;align-items:center;flex:1 1 auto;min-width:0}.seatreg-tabs-content .custom-container label input[type=text],.seatreg-tabs-content .custom-container label select{flex:1 1 auto;min-width:40px;width:auto}.seatreg-tabs-content .custom-container .custom-container-controls{display:flex;align-items:center;flex:0 0 auto;column-gap:4px;margin-left:auto}.seatreg-tabs-content .custom-container .l-text{display:inline-block;min-width:76px;max-width:76px;overflow:hidden;text-overflow:ellipsis}.seatreg-tabs-content .custom-container-move{border:1px solid #ccc;border-radius:4px;padding:2px;cursor:pointer}.seatreg-tabs-content .custom-container-move:hover{background-color:#ccc}.seatreg-tabs-content .custom-container-move-highlight{background-color:#ee0}.seatreg-tabs-content .existing-custom-fields{margin-left:24px}.seatreg-tabs-content .payment-configuration{margin-top:12px;margin-left:24px}#paypal-webhook-check-result:not(:empty),#stripe-webhook-check-result:not(:empty){margin-top:12px}.webhook-check-list{margin:0;padding:0;list-style:none}.webhook-check-list li{margin-bottom:4px}.webhook-check-list .webhook-check-ok{color:#46b450}.webhook-check-list .webhook-check-failed{color:#dc3232}.webhook-check-list .webhook-check-detail{color:#666;word-break:break-all}.seatreg-tabs-content .custom-container input[type=checkbox]{margin-top:0}.seatreg-tabs-content .remove-cust-item{cursor:pointer;color:red;margin-left:6px}.seatreg-tabs-content .cust-field-create{margin-top:10px;margin-left:24px}.seatreg-tabs-content .select-radio-create{margin-bottom:12px}.seatreg-tabs-content .seatreg-settings-form input[type=number],.seatreg-tabs-content .seatreg-settings-form input[type=text]{height:32px;font-size:14px}.seatreg-tabs-content .cust-field-create label,.seatreg-tabs-content .seatreg-settings-form textarea{font-size:14px}.seatreg-tabs-content .cust-field-create .btn{margin-bottom:.5rem}.seatreg-tabs-content .select-option{margin-bottom:6px}.seatreg-tabs-content .cust-input-label{margin-right:10px;width:140px}.seatreg-tabs-content .custom-field-select{margin-right:10px}.seatreg-tabs-content .manager-search-wrap{width:200px;margin-top:6px;float:right}.seatreg-tabs-content .manager-search{border-color:#ccc;border-right:0;height:calc(1.5rem + .75rem + 2px);min-height:calc(1.5rem + .75rem + 2px)}.seatreg-tabs-content .manager-search:focus{box-shadow:none;border-color:#ccc;border-right:0}.seatreg-tabs-content .option-input{width:170px;margin:10px 10px 20px 0;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.seatreg-tabs-content .option-label{font-size:16px}.seatreg-tabs-content .l-text{margin-right:10px;font-size:14px}.seatreg-tabs-content .edit-btn{cursor:pointer}.seatreg-tabs-content .create-new-registration-wrapper{margin-top:20px;margin-bottom:20px;font-weight:700}.seatreg-tabs-content .admin-btn-from{border-bottom:1px solid #e1e5e7}.seatreg-tabs-content .room-list-item[data-active=true]{color:orange}.seatreg-tabs-content .file-type-link{float:right;margin-top:10px;margin-right:20px;font-size:18px;color:#000}.seatreg-map-popup-btn{color:#428bca;font-size:14px}.seatreg-delete-btn,.seatreg-map-popup-btn{padding:0}.seatreg_page_seatreg-management .booking-status-check-wrap input[type=checkbox]{margin-top:0;margin-left:6px}.seatreg-wp-admin .search-button{border-top-left-radius:0;border-bottom-left-radius:0}.seatreg-wp-admin .payment-log-wrap{display:grid;grid-gap:10px;grid-template-columns:minmax(40px,auto) 140px 1fr;color:#228b22}.seatreg-wp-admin .payment-log-wrap .error-log{color:red}.seatreg-wp-admin .payment-log-wrap .info-log{color:#00f}.seatreg-wp-admin .add-payment-log-wrap{display:flex;align-items:center;margin-top:12px}.seatreg-wp-admin .add-payment-log-wrap input,.seatreg-wp-admin .add-payment-log-wrap select{margin-right:12px}@media screen and (max-width:1199px){.seatreg-tabs-content #my-regs{width:970px;padding:0 15px}.seatreg-tabs-content .admin-right-side{width:700px;margin-right:5px}.seatreg-tabs-content .reg-overview-middle{width:440px}.seatreg-tabs-content .overview-middle-box{margin-right:30px}.seatreg-tabs-content .action-select{margin-top:10px;text-align:right;float:right}.seatreg-tabs-content .bg-color{padding-top:80px;background-color:#f2f2f2}}@media screen and (max-width:800px){.seatreg-tabs-content .manager-box{display:block;text-align:left}.seatreg-tabs-content .file-type-link{position:absolute;top:0;margin:0}.seatreg-tabs-content .pdf-link{right:0}.seatreg-tabs-content .text-link{right:150px}.seatreg-tabs-content .xlsx-link{right:70px}.seatreg-tabs-content .manager-search-wrap{margin-top:40px}.seatreg-tabs-content .action-select{float:none;text-align:right;display:block;margin-top:10px}}@media screen and (max-width:992px){.seatreg-tabs-content .reg-section-buttons{width:20%}.seatreg-tabs-content .reg-overview-middle-wrap{display:block}.seatreg-tabs-content #my-regs{width:auto}.seatreg-tabs-content .reg-overview{width:100%}.seatreg-tabs-content .admin-right-side{width:70%;margin:0}.seatreg-tabs-content .reg-overview-aside{float:none;width:100%;max-height:none;min-height:0;text-align:center;margin-bottom:0;padding-right:0}.seatreg-tabs-content .reg-overview-middle{float:none;overflow:hidden;width:100%;padding:20px 20px 10px;margin:0;text-align:center}.seatreg-tabs-content .reg-overview-top-date{float:none;clear:both;text-align:center;margin-top:10px}.seatreg-tabs-content .reg-overview-top-bron-notify{height:30px;margin-bottom:10px;margin-top:10px;float:none;text-align:center}.seatreg-tabs-content .reg-overview-top-bron-notify,.seatreg-tabs-content .reg-overview-top-date,.seatreg-tabs-content .reg-overview-top-header{line-height:20px}.seatreg-tabs-content .time-block{display:inline-block;margin-bottom:4px}.seatreg-tabs-content .reg-link{width:100%;word-wrap:break-word;word-break:break-all}.seatreg-tabs-content .reg-overview-top-header{float:none;text-align:center;word-wrap:break-word;margin-top:20px}.seatreg-tabs-content .overview-middle-box{display:inline-block;float:none;margin:0 4px}.seatreg-tabs-content .room-list-item{display:inline-block;margin-right:20px}.seatreg-tabs-content #alertify{top:30%}.seatreg-tabs-content .reg-overview-donuts{display:block;width:100%;margin:0;text-align:center;float:none;padding:0}.seatreg-tabs-content .reg-overview-top{padding-top:6px;padding-bottom:0;margin-bottom:10px}.seatreg-tabs-content .reg-overview-bottom{clear:both;margin-top:20px}.seatreg-tabs-content .stats-doughnut{margin:0}.seatreg-tabs-content .legend-block{text-align:left}.seatreg-tabs-content .stats-doughnut-legend{margin-left:0}}@media screen and (max-width:776px){.seatreg-tabs-content .reg-section-buttons{width:25%}.seatreg-tabs-content .admin-btn-from,.seatreg-tabs-content .btn-style,.seatreg-tabs-content .del-reg,.seatreg-tabs-content .del-reg-form{width:100%;margin-bottom:4px}.seatreg-tabs-content .account-status{margin-bottom:0}.seatreg-tabs-content .first-reg-section .tab_container:before{margin-top:-300px;height:300px}.seatreg-tabs-content .tab_container:before{margin-top:-310px;height:310px}.seatreg-tabs-content .tab a{padding:0}}@media screen and (max-width:900px){.seatreg-tabs-content .first-reg-section .tab_container:before{margin-top:-330px;height:330px}.seatreg-tabs-content .tab_container:before{margin-top:-250px;height:250px}}@media screen and (max-width:500px){.seatreg-tabs-content .bg-color{padding-top:100px;background-color:#f2f2f2}.seatreg-tabs-content .reg-section-buttons{font-size:12px}.seatreg-tabs-content .first-reg-section .tab_container:before,.seatreg-tabs-content .tab_container:before{margin-top:-330px;height:330px}.seatreg-tabs-content .custom-container input[type=text]{width:60px}}#calendar-dates-list .calendar-date-chip{display:inline-flex;align-items:center;margin:2px 4px 2px 0;padding:2px 4px 2px 8px;background-color:#e7f3ff;border:1px solid #b8daff;border-radius:3px;font-size:12px;color:#04357d}#calendar-dates-list .calendar-date-chip-remove{margin-left:6px;padding:0 3px;border:none;background:0 0;color:#04357d;font-size:14px;line-height:1;cursor:pointer;opacity:.7}#calendar-dates-list .calendar-date-chip-remove:hover{opacity:1;color:#c00}
     1.seatreg-tabs-content .add-modal .bottom-action .seat-operations .seat-operation:hover,.seatreg-tabs-content .management-header .management-extra-actions .add-booking:hover span,.seatreg-tabs-content .management-header .management-extra-actions .import-bookings:hover span,.seatreg-tabs-content .seat-id-modal .seat-id-grid .grid-title,.seatreg-wp-admin .nav-tab.nav-tab-active{text-decoration:underline}.seatreg-tabs-content .edit-modal h5{margin-bottom:0}.seatreg-tabs-content .edit-modal .edit-modal-input-wrap,.seatreg-tabs-content .edit-modal .modal-custom{margin-bottom:12px}.seatreg-tabs-content .add-modal h5{margin-bottom:.5rem}.seatreg-tabs-content .add-modal .add-modal-input-wrap{margin-bottom:12px}.seatreg-tabs-content .add-modal .add-modal-input-wrap .seat-id-search{vertical-align:middle;padding-top:20px;margin-left:4px;cursor:pointer}.seatreg-tabs-content .add-modal .modal-custom{margin-bottom:12px}.seatreg-tabs-content .add-modal .add-modal-calendar-date{display:flex;justify-content:center;align-items:center}.seatreg-tabs-content .add-modal .add-modal-calendar-date .fa{margin-right:8px}.seatreg-tabs-content .add-modal .modal-body-items{display:flex;overflow-x:auto}.seatreg-tabs-content .add-modal .modal-body-items .modal-body-item:not(:last-child){margin-right:24px}.seatreg-tabs-content .add-modal .modal-body-items .modal-body-item .input-error{color:red}.seatreg-tabs-content .add-modal .bottom-action{margin-top:24px}.seatreg-tabs-content .add-modal .bottom-action .seat-operations{display:flex;justify-content:center;margin-bottom:12px}.seatreg-tabs-content .add-modal .bottom-action .seat-operations .seat-operation{cursor:pointer}.seatreg-tabs-content .add-modal .bottom-action .seat-operations .seat-operation:first-child{margin-right:12px}.seatreg-tabs-content .add-modal .bottom-action .fa-plus-circle{color:#61B329}.seatreg-tabs-content .add-modal .bottom-action .bottom-action-item__input-error,.seatreg-tabs-content .add-modal .bottom-action .fa-minus-circle{color:red}.seatreg-tabs-content .add-modal .bottom-action .bottom-action-item{cursor:pointer;text-align:center;margin-bottom:12px}.seatreg-tabs-content .add-modal .bottom-action .bottom-action-item__title{font-weight:700}.seatreg-wp-admin .activity-modal__loading{text-align:center}.seatreg-wp-admin .activity-modal__logs{display:grid;grid-template-columns:200px 1fr}#seatreg-booking-manager .bookings-file-modal .date-info{display:flex;justify-content:center;align-items:center;margin-bottom:12px}#seatreg-booking-manager .bookings-file-modal .date-info .fa{margin-right:8px}#seatreg-booking-manager .bookings-file-modal input{margin-left:8px}#seatreg-booking-manager .bookings-file-modal .fa-plus-circle{color:#61B329}#seatreg-booking-manager .bookings-file-modal .form-fields{margin-bottom:12px}#seatreg-booking-manager .bookings-file-modal .custom-filtering{cursor:pointer}#seatreg-booking-manager .bookings-file-modal .custom-filtering-selection{display:none;margin-top:12px}.seatreg-tabs-content .seat-id-modal h5{margin-top:8px}.seatreg-tabs-content .seat-id-modal .seat-id-grid{display:grid;row-gap:8px;grid-template-columns:auto 1fr 1fr;margin-left:40px;grid-column-gap:30px}.seatreg-tabs-content .seat-id-modal .seat-id-grid .grid-title{margin-bottom:8px}#import-bookings-modal .import-booking-modal-error{color:#E0635D;font-size:14px;margin-top:8px}#import-bookings-modal .import-booking-modal-loading{display:flex;flex-direction:column;align-items:center}#import-bookings-modal .import-booking-modal-loading img{margin-bottom:8px}#seatreg-booking-manager .import-bookings-finalization-modal__body{max-height:70vh;overflow-y:auto}#seatreg-booking-manager .import-bookings-finalization-modal__booking{display:flex;align-items:center;border:1px solid #ccc;padding:8px 12px;gap:6px;margin-bottom:8px}#seatreg-booking-manager .import-bookings-finalization-modal__booking--invalid{border-color:#d10516}#seatreg-booking-manager .import-bookings-finalization-modal__trash-icon,#seatreg-booking-manager .import-bookings-finalization-modal__warning-icon{margin-left:auto;color:red;cursor:pointer}#seatreg-booking-manager .import-bookings-finalization-modal__popup{max-width:400px}#seatreg-booking-manager .import-bookings-finalization-modal .warn-text{color:#d10516;font-weight:700}.seatreg-wp-admin .shortcode-modal .shortcode-instructions{margin-top:12px;margin-bottom:0}.seatreg-tabs-content .ajax_loader{position:fixed;top:50%;left:50%;margin-left:-32px;margin-top:-32px;z-index:9999}@media screen and (max-width:992px){.seatreg-tabs-content .ajax_loader{top:20%;left:50%;margin-left:-32px;margin-top:-32px}}.seatreg-tabs-content .management-header{position:relative;display:flex;flex-wrap:wrap;justify-content:space-between;background-color:#F2F2F2;text-transform:uppercase;font-size:20px;min-height:42px;padding:6px 6px 16px}.seatreg-tabs-content .management-header>div{min-width:150px}.seatreg-tabs-content .management-header .pending-bookings-count{color:#E0635D}.seatreg-tabs-content .management-header .management-extra-actions{display:flex;gap:12px;text-transform:none}.seatreg-tabs-content .management-header .management-extra-actions .add-booking{cursor:pointer}.seatreg-tabs-content .management-header .management-extra-actions .add-booking .fa-plus-circle{color:#61B329}.seatreg-tabs-content .management-header .management-extra-actions .import-bookings{cursor:pointer}.seatreg-tabs-content .management-header .management-extra-actions .import-bookings .fa{color:#4ea8f0}.seatreg-tabs-content .management-header .booking-manager-calendar-wrap{width:100%;display:flex;justify-content:center;align-items:center;margin-bottom:12px}.seatreg-tabs-content .management-header .booking-manager-calendar-wrap label{margin-bottom:0}.seatreg-tabs-content .management-header .booking-manager-calendar-wrap input{text-align:center;margin-left:12px;width:170px}.reg-more-items{display:flex;flex-wrap:wrap}.reg-more-items__item{padding:24px;border:1px solid #ccc;border-radius:3px;margin-right:12px;cursor:pointer}.reg-more-items__item:hover{box-shadow:1px 1px 10px 0 rgba(204,204,204,.52)}.reg-more-items__item--delete-form{padding:0}#seatreg-booking-manager .custom-fields .custom-field{display:flex;align-items:center;margin-bottom:8px}#seatreg-booking-manager .custom-fields .custom-field input,#seatreg-booking-manager .custom-fields .custom-field label{margin-bottom:0}#seatreg-booking-manager .custom-fields .custom-field .fa{cursor:pointer;margin-left:8px}#seatreg-settings-form #public-api-tokens{margin-left:24px;margin-bottom:12px}#seatreg-settings-form #public-api-tokens .token-box{display:flex;align-items:center;border:1px solid #ccc;padding:12px;border-radius:4px;column-gap:6px;margin-bottom:12px}#seatreg-settings-form #public-api-tokens .token-box .token-actions{margin-left:auto}#seatreg-settings-form #custom-payments,#seatreg-settings-form .coupon-box__actions,#seatreg-settings-form .coupon-create,#seatreg-settings-form .existing-coupons{margin-left:24px}#seatreg-settings-form #public-api-tokens .token-box .token-actions .remove-token{color:red;cursor:pointer}#seatreg-settings-form #custom-payments .custom-payment{border:1px solid #ccc;padding:12px;border-radius:4px;display:grid;grid-template-columns:auto 1fr;column-gap:24px;row-gap:12px;margin-bottom:24px}#seatreg-settings-form #custom-payments .custom-payment__controls{text-align:center;grid-column:span 2}#seatreg-settings-form .custom-payment-icon-upload{display:flex}#seatreg-settings-form .custom-payment-icon-upload__error{color:red}#seatreg-settings-form .custom-payment-icon-upload__loading{margin-right:8px;display:none}#seatreg-settings-form .current-custom-payment-icon{display:flex;align-items:center}#seatreg-settings-form .current-custom-payment-icon__loading,.settings-tab-panel{display:none}#seatreg-settings-form .current-custom-payment-icon__img{height:74px;margin-right:12px}#seatreg-settings-form .current-custom-payment-icon__delete{cursor:pointer;color:red}#seatreg-booking-manager .approved-booking-email-text{margin-top:12px;display:flex;flex-direction:column;align-items:start;gap:6px}#seatreg-booking-manager .approved-booking-email-text__input-wrapper{display:flex;align-items:center;gap:6px}#seatreg-booking-manager .approved-booking-email-text__warning{color:red}#seatreg-settings-form .existing-coupons{margin-bottom:24px}#seatreg-settings-form .new-coupon{display:flex;align-items:center;gap:8px}#seatreg-settings-form .new-coupon input[type=text]{width:120px}#seatreg-settings-form .new-coupon input[type=number]{width:80px}#seatreg-settings-form .new-coupon__label{font-size:14px;margin-bottom:0}#seatreg-settings-form .coupon-box{display:flex;align-items:center;margin-bottom:12px}#seatreg-settings-form .coupon-box__label{margin-right:8px;font-size:14px}#seatreg-settings-form .coupon-box__value{font-weight:600;min-width:80px}.seatreg-wp-admin .companion-app-form .submit{margin-top:8px}@keyframes shake{0%{transform:translate(1px,1px) rotate(0)}10%{transform:translate(-1px,-2px) rotate(-1deg)}20%{transform:translate(-3px,0) rotate(1deg)}30%{transform:translate(3px,2px) rotate(0)}40%{transform:translate(1px,-1px) rotate(1deg)}50%{transform:translate(-1px,2px) rotate(-1deg)}60%{transform:translate(-3px,1px) rotate(0)}100%,70%{transform:translate(0,0) rotate(0)}}.seatreg-flower-layer{position:absolute;inset:0;z-index:-1;overflow:hidden;pointer-events:none}.seatreg-flower-container{--flower-size:12px;--flower-delay:0s;--flower-opacity:0.2;--flower-petal-reach:calc(var(--flower-size) * 1.42);width:calc(var(--flower-petal-reach) * 2);height:calc(var(--flower-petal-reach) * 2);position:absolute}.seatreg-flower-droplet{border-radius:5px 90%;border-style:solid;border-width:1px;height:var(--flower-size);width:var(--flower-size);position:absolute;top:50%;left:50%;transform-origin:left top;opacity:0}.seatreg-flower-droplet-1{background:#428bca;animation:spin1 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + 0s)}.seatreg-flower-droplet-2{background:#2271b1;animation:spin2 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .05s)}.seatreg-flower-droplet-3{background:#428bca;animation:spin3 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .1s)}.seatreg-flower-droplet-4{background:#2271b1;animation:spin4 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .15s)}.seatreg-flower-droplet-5{background:#428bca;animation:spin5 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .2s)}.seatreg-flower-droplet-6{background:#2271b1;animation:spin6 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .25s)}.seatreg-flower-droplet-7{background:#428bca;animation:spin7 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .3s)}.seatreg-flower-droplet-8{background:#2271b1;animation:spin8 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .35s)}.seatreg-flower-droplet-9{background:#428bca;animation:spin9 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .4s)}.seatreg-flower-droplet-10{background:#2271b1;animation:spin10 5s ease-out;animation-fill-mode:forwards;animation-delay:calc(var(--flower-delay) + .45s)}@keyframes spin1{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(324deg) scale(1);transform:rotate(324deg) scale(1)}}@keyframes spin2{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(288deg) scale(1);transform:rotate(288deg) scale(1)}}@keyframes spin3{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(252deg) scale(1);transform:rotate(252deg) scale(1)}}@keyframes spin4{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(216deg) scale(1);transform:rotate(216deg) scale(1)}}@keyframes spin5{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(180deg) scale(1);transform:rotate(180deg) scale(1)}}@keyframes spin6{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(144deg) scale(1);transform:rotate(144deg) scale(1)}}@keyframes spin7{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(108deg) scale(1);transform:rotate(108deg) scale(1)}}@keyframes spin8{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(72deg) scale(1);transform:rotate(72deg) scale(1)}}@keyframes spin9{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(36deg) scale(1);transform:rotate(36deg) scale(1)}}@keyframes spin10{0%{opacity:0;-webkit-transform:rotate(0) scale(.01);transform:rotate(0) scale(.01)}100%,20%,60%{opacity:var(--flower-opacity);-webkit-transform:rotate(0) scale(1);transform:rotate(0) scale(1)}}.seatreg-wp-admin .seatreg-update-notice{position:absolute;left:15px;bottom:100%;margin-bottom:10px;font-size:13px}.seatreg-registrations{--seatreg-donate-rows:3;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-flow:row dense;gap:16px;margin-bottom:32px}.seatreg-registrations #create-registration-form,.seatreg-registrations .donate-wrap,.seatreg-registrations .your-registrations-header{grid-column:1/-1}.seatreg-registrations .donate-wrap{align-self:start}@media screen and (min-width:860px){.seatreg-registrations{grid-template-columns:repeat(3,minmax(0,1fr))}.seatreg-registrations #create-registration-form,.seatreg-registrations .seatreg-registrations-empty,.seatreg-registrations .your-registrations-header{grid-column:1/-3}.seatreg-registrations .donate-wrap{grid-row:1/span var(--seatreg-donate-rows);grid-column:-3/-1}}@media screen and (min-width:1250px){.seatreg-registrations{grid-template-columns:repeat(4,minmax(0,1fr))}}@media screen and (min-width:1600px){.seatreg-registrations{grid-template-columns:repeat(5,minmax(0,1fr))}}@media screen and (min-width:1900px){.seatreg-registrations{grid-template-columns:repeat(6,minmax(0,1fr))}}.seatreg-registrations-empty{grid-column:1/-1;margin-top:28px;padding:24px;border:1px dashed #c3c4c7;border-radius:4px;color:#646970}.seatreg-registration-card{display:flex;font-size:13px;flex-direction:column;row-gap:8px;padding:16px;background-color:#fff;border:1px solid #dcdcde;border-radius:4px}.seatreg-registration-card__head{display:flex;align-items:flex-start;justify-content:space-between;column-gap:8px}.seatreg-registration-card__status{display:flex;flex-shrink:0;align-items:center;column-gap:6px}.seatreg-registration-card__calendar-icon{color:#646970;font-size:14px}.seatreg-registration-card__title{margin:0;overflow-wrap:anywhere}.seatreg-registration-card__title .registration-name-link{color:#333;font-size:18px}.seatreg-registration-card__badge{flex-shrink:0;padding:4px 8px;color:#fff;font-size:12px;font-weight:600}.seatreg-registration-card__badge--open{background-color:#2e7d32}.seatreg-registration-card__badge--scheduled{background-color:#0073aa}.seatreg-registration-card__badge--closed{background-color:#8c8f94}.seatreg-registration-card__badge--ended{background-color:#50575e}.seatreg-registration-card__meta{color:#646970;font-size:13px}.seatreg-registration-card__actions{display:flex;flex-direction:column;align-items:flex-start;row-gap:4px;padding-top:4px}.seatreg-registration-card__actions .btn-link,.seatreg-registration-card__actions a{padding:0;color:#428bca;font-size:14px;text-align:left}.seatreg-registration-card__footer{display:flex;flex-direction:column;row-gap:8px;margin-top:auto;padding-top:12px;border-top:1px solid #c3c4c7}.seatreg-registration-card__footer-date{color:#646970;font-size:12px}.seatreg-registration-card__footer-date .fa{margin-right:4px}.seatreg-registration-card__footer-notice{color:#646970;font-size:13px;font-style:italic}.seatreg-registration-card__stats{display:flex;column-gap:8px}.seatreg-registration-card__stat{display:flex;flex:1;flex-direction:column;text-decoration:none}.seatreg-registration-card__stat:focus,.seatreg-registration-card__stat:hover{text-decoration:none}.seatreg-registration-card__stat:focus .seatreg-registration-card__stat-value,.seatreg-registration-card__stat:hover .seatreg-registration-card__stat-value{color:#428bca}.seatreg-registration-card__stat--highlight .seatreg-registration-card__stat-value{color:#b32d2e}.seatreg-registration-card__stat-value{color:#646970;font-size:18px;font-weight:600;line-height:1.2}.seatreg-registration-card__stat-label{color:#8c8f94;font-size:12px}@media screen and (max-width:782px){.seatreg-registrations{grid-template-columns:minmax(0,1fr)}}.seatreg-overview{--seatreg-overview-confirmed:#2e7d32;--seatreg-overview-pending:#dba617;--seatreg-overview-open:#2271b1;--seatreg-overview-unavailable:#dcdcde;font-size:13px}.seatreg-overview__head{display:flex;flex-wrap:wrap;align-items:center;column-gap:16px;row-gap:8px;padding-bottom:16px;border-bottom:1px solid #dcdcde}.seatreg-overview__identity{display:flex;align-items:center;column-gap:8px;margin-right:auto}.seatreg-overview__title{margin:0;font-size:20px;overflow-wrap:anywhere}.seatreg-overview__calendar-icon{color:#646970;font-size:14px}.seatreg-overview__dates{color:#646970}.seatreg-overview__links{display:flex;column-gap:16px}.seatreg-overview__links a{color:#428bca;font-size:14px}.seatreg-overview__toolbar{display:flex;flex-wrap:wrap;align-items:center;column-gap:24px;row-gap:8px;margin-top:16px}.seatreg-overview__toolbar-field{display:flex;align-items:center;column-gap:12px}.seatreg-overview__toolbar-field label{margin-bottom:0;color:#646970;text-transform:uppercase}.seatreg-overview__toolbar-field input{width:170px;text-align:center}.seatreg-overview__toolbar-field select{min-width:130px}.seatreg-overview__empty{margin-top:24px;padding:24px;border:1px dashed #c3c4c7;border-radius:4px;color:#646970}.seatreg-overview__body{display:grid;grid-template-columns:minmax(0,260px) minmax(0,1fr);gap:24px;margin-top:24px}.seatreg-overview__rooms{display:flex;flex-direction:column;row-gap:4px}.seatreg-overview__room{display:flex;flex-direction:column;row-gap:6px;padding:10px 12px;background-color:#fff;border:1px solid #dcdcde;border-radius:4px;text-align:left;cursor:pointer}.seatreg-overview__room:hover{border-color:#2271b1}.seatreg-overview__room:focus-visible{outline:#2271b1 solid 2px;outline-offset:1px}.seatreg-overview__room[aria-selected=true]{border-color:#2271b1;box-shadow:inset 3px 0 0 #2271b1}.seatreg-overview__room-head{display:flex;align-items:baseline;justify-content:space-between;column-gap:8px}.seatreg-overview__room-name{font-size:14px;font-weight:600;overflow-wrap:anywhere}.seatreg-overview__room-count{flex-shrink:0;color:#646970;font-size:12px}.seatreg-overview__bar{display:flex;height:6px;background-color:var(--seatreg-overview-unavailable);border-radius:3px;overflow:hidden}.seatreg-overview__bar-segment{height:100%}.seatreg-overview__bar-segment--confirmed{background-color:var(--seatreg-overview-confirmed)}.seatreg-overview__bar-segment--pending{background-color:var(--seatreg-overview-pending)}.seatreg-overview__bar-segment--open{background-color:var(--seatreg-overview-open)}.seatreg-overview__panel{padding:20px;background-color:#fff;border:1px solid #dcdcde;border-radius:4px}.seatreg-overview__panel:focus-visible{outline:#2271b1 solid 2px;outline-offset:1px}.seatreg-overview__panel-title{margin:0 0 20px;font-size:16px;overflow-wrap:anywhere}.seatreg-overview__stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}.seatreg-overview__stat{display:flex;flex-direction:column;text-decoration:none}.seatreg-overview__stat--link:focus,.seatreg-overview__stat--link:hover{text-decoration:none}.seatreg-overview__stat--link:focus .seatreg-overview__stat-value,.seatreg-overview__stat--link:hover .seatreg-overview__stat-value{color:#428bca}.seatreg-overview__stat--highlight .seatreg-overview__stat-value{color:#b32d2e}.seatreg-overview__stat-value{color:#1d2327;font-size:32px;font-weight:600;line-height:1.2}.seatreg-overview__stat-label{color:#8c8f94;font-size:12px}.seatreg-overview__sprite{position:absolute;width:0;height:0;overflow:hidden}.seatreg-overview__chart{display:flex;flex-direction:column;row-gap:16px;margin-top:24px;padding-top:20px;border-top:1px solid #dcdcde}.seatreg-overview__chart-types{display:flex;column-gap:4px}.seatreg-overview__chart-type{display:flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;color:#646970;background-color:#fff;border:1px solid #dcdcde;border-radius:4px;cursor:pointer}.seatreg-overview__chart-type:hover{color:#2271b1;border-color:#2271b1}.seatreg-overview__chart-type:focus-visible{outline:#2271b1 solid 2px;outline-offset:1px}.seatreg-overview__chart-type[aria-pressed=true]{color:#fff;background-color:#2271b1;border-color:#2271b1}.seatreg-overview__chart-icon{width:16px;height:16px}.seatreg-overview__chart-body{display:flex;flex-wrap:wrap;align-items:center;column-gap:32px;row-gap:16px}.seatreg-overview__canvas-wrap{position:relative;flex:1 1 260px;max-width:380px;height:200px}.seatreg-overview__legend{display:flex;flex-direction:column;row-gap:8px;min-width:180px}.seatreg-overview__legend-row{display:flex;align-items:center;column-gap:10px}.seatreg-overview__legend-swatch{width:12px;height:12px;flex-shrink:0;border-radius:50%}.seatreg-overview__legend-swatch--confirmed{background-color:var(--seatreg-overview-confirmed)}.seatreg-overview__legend-swatch--pending{background-color:var(--seatreg-overview-pending)}.seatreg-overview__legend-swatch--open{background-color:var(--seatreg-overview-open)}.seatreg-overview__legend-label{margin-right:auto}.seatreg-overview__legend-percent{color:#646970;font-variant-numeric:tabular-nums}@media screen and (max-width:992px){.seatreg-overview__body{grid-template-columns:minmax(0,1fr)}}@media screen and (max-width:782px){.seatreg-overview__stats{grid-template-columns:repeat(2,minmax(0,1fr))}}html{font-size:100%}.index-icon{margin-right:10px}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:active,.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.seatreg-wp-admin .btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.seatreg-wp-admin .btn-primary:active,.seatreg-wp-admin .btn-primary:hover{background-color:#3276b1;border-color:#285e8e}.seatreg-wp-admin input[type=checkbox]:focus{outline:0}.seatreg-wp-admin{font-family:"Open Sans",sans-serif}.seatreg-wp-admin .home-content{display:flow-root;position:relative}.seatreg-wp-admin .jumbotron{background-image:url(../img/chairs_med.jpg);background-size:cover;margin-left:-20px;margin-bottom:42px}.seatreg-wp-admin .donate-wrap{max-width:100%;display:flex;flex-direction:column;padding:0 15px;align-items:center;text-align:center;row-gap:12px;position:relative;isolation:isolate}.seatreg-wp-admin .donate-wrap p{margin-bottom:.6rem}.seatreg-wp-admin .donate-wrap>img{margin-right:12px}.seatreg-wp-admin .donate-wrap .donate-paypal{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px}.seatreg-wp-admin .donate-wrap .donate-paypal p{margin:0}.seatreg-wp-admin .donate-wrap .donate-paypal form{display:flex;margin:0}.seatreg-wp-admin .donate-wrap .donate-img{cursor:pointer;transition:transform .15s ease,filter .15s ease;animation:shake 1s;animation-delay:1s;animation-iteration-count:10}.seatreg-wp-admin .donate-wrap .donate-img:focus-visible,.seatreg-wp-admin .donate-wrap .donate-img:hover{transform:scale(1.05);filter:brightness(1.08)}.seatreg-wp-admin .donate-wrap .buy-me-coffee-link img{width:120px}.seatreg-wp-admin .your-registrations-header{margin-top:28px;margin-bottom:24px}.seatreg-wp-admin .nav-tab:first-of-type{margin-left:0}.seatreg-wp-admin .nav-tab{background:#f2f2f2}.new-reg-title{margin-bottom:24px}.seatreg-wp-admin .jumbotron .main-heading{font-size:38px;font-weight:600}.seatreg-wp-admin .jumbotron .jumbotron-text{font-size:21px;font-weight:600}.seatreg-wp-admin .nav-tabs{margin-top:40px}.seatreg-tabs-content{background-color:#f2f2f2;padding:24px;border:1px solid #ccc;border-top:none;position:relative}.seatreg-tabs-content .etabs{margin:0;padding:0 0 6px;background-color:#f2f2f2}.seatreg-tabs-content .tab{display:inline-block;margin-right:2px;padding:6px;zoom:1;background:#fff}.seatreg-tabs-content .tab a{font-size:16px;line-height:2em;display:block;padding:0 30px;outline:0;text-decoration:none;color:#000}.seatreg-tabs-content .action-control:hover,.seatreg-tabs-content .btn-style:hover,.seatreg-tabs-content .del-reg:hover,.seatreg-tabs-content .manager-box-link:hover,.seatreg-tabs-content .tab a:hover,.settings-tab:hover{text-decoration:underline}.seatreg-tabs-content .tab.active{background:#404040;position:relative}.seatreg-tabs-content .tab a.active{font-weight:700;color:#fff}.seatreg-tabs-content .tab-container .panel-container{overflow:hidden}.seatreg-tabs-content .form-group{margin-bottom:25px}.seatreg-settings-form .form-group{max-width:600px}.seatreg-settings-form .form-group-title{margin:0 0 5px;font-size:16px}.seatreg-settings-form .form-group-subfield-label{margin-bottom:2px;font-size:13px}.seatreg-settings-form .flow-summary-group{max-width:none}.settings-tabs{display:flex;flex-wrap:wrap;gap:10px;margin:16px 0 0;padding:0;background-color:#f2f2f2}.settings-tab{background:#fff;border:none;padding:6px 24px;cursor:pointer;font-size:16px;line-height:2em;color:#000}.settings-tab.settings-tab--active{background:#404040;font-weight:700;color:#fff}.settings-tab.settings-tab--active:hover{text-decoration:none}.settings-tab-panels{padding:32px 0 0;background:0 0}.settings-tab-panel.settings-tab-panel--active{display:block}.email-color-fields{display:grid;grid-template-columns:max-content max-content;align-items:center;gap:10px 16px;margin-top:12px}.email-logo-controls{display:flex;align-items:center;gap:12px;margin:12px 0;flex-wrap:wrap}#email-logo-preview,#page-logo-preview{max-height:60px;max-width:200px;border:1px solid #e2e8f0;border-radius:4px;padding:4px;background:#fff}.email-color-field{display:contents}.email-color-field label{font-size:13px;margin:0}.email-color-field input[type=color]{width:48px;height:32px;padding:0;border:1px solid #ccc;border-radius:4px;cursor:pointer}.email-color-field input[type=color]:disabled{opacity:.5;cursor:not-allowed}.seatreg-settings-form #seatreg-settings-submit{margin-top:20px}.booking-flow-details__summary{cursor:pointer;font-weight:700;font-size:14px;padding:4px 0;user-select:none;list-style:none;display:flex;align-items:center;color:#2271b1}.booking-flow-details__summary::-webkit-details-marker{display:none}.booking-flow-details__summary:hover{color:#135e96}.booking-flow-details__icon{margin-right:8px;transition:transform .15s ease}.booking-flow-details[open] .booking-flow-details__icon{transform:rotate(90deg)}.booking-flow-details__hint{font-weight:400;font-size:12px;color:#777;margin-left:8px}.booking-flow-details .help-block{margin-top:10px}#booking-flow-summary .flow-group{margin-bottom:12px}#booking-flow-summary .flow-group:last-child{margin-bottom:0}#booking-flow-summary .flow-group__title{font-weight:600;margin-bottom:4px}#booking-flow-summary .flow-group__list{margin:0;padding-left:20px;list-style:disc}#booking-flow-summary .flow-group__list li{margin-bottom:3px}#booking-flow-summary .flow-jump{margin-left:6px;font-size:12px;color:#2271b1;text-decoration:none}#booking-flow-summary .flow-jump:hover{color:#135e96}.flow-jump-highlight{animation:seatregFlowHighlight 1.6s ease;border-radius:4px}@keyframes seatregFlowHighlight{0%{background-color:#fff3b0}100%{background-color:transparent}}.seatreg-tabs-content #admin-wrapper{width:960px;margin:0 auto;font-family:"Open Sans",sans-serif}.seatreg-tabs-content #my-regs{width:1170px;margin:0 auto;padding:0 15px}.seatreg-tabs-content #server-response-text{font-size:20px}.seatreg-tabs-content .log-out-btn{display:block;float:right;text-decoration:none;width:150px;height:33px;line-height:33px;font-size:18px}.seatreg-tabs-content .log-out-btn .l-pic{float:left;background:url(sprites.png) -5px -388px no-repeat;width:32px;height:33px;padding-right:10px}.seatreg-tabs-content .reg-seat-item,.seatreg-tabs-content .registration-manager-labels{border-bottom:3px solid #f0f0f0;padding:16px;background-color:#fff}.seatreg-tabs-content .reg-section{overflow:hidden;min-height:608px}.seatreg-tabs-content .tab_container{overflow:visible!important}.seatreg-tabs-content .panel-container .tab_container{display:none}.seatreg-tabs-content .panel-container .tab_container.active{display:block}.seatreg-tabs-content .first-reg-section .tab_container:before{display:block;content:" ";margin-top:-240px;height:240px;visibility:hidden}.seatreg-tabs-content .tab_container:before{display:block;content:" ";margin-top:-170px;height:170px;visibility:hidden}.seatreg-tabs-content .reg-seat-item{font-size:14px;overflow:hidden}.seatreg-tabs-content .seat-nr-box{width:60px}.seatreg-tabs-content .seat-date-box,.seatreg-tabs-content .seat-name-box,.seatreg-tabs-content .seat-room-box{width:140px;text-align:center}.seatreg-tabs-content .seat-id-box{margin-right:30px}.seatreg-tabs-content .booking-status-box{margin-left:180px}.seatreg-tabs-content .seat-name-box{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;vertical-align:middle}.seatreg-tabs-content .payment-status-box{min-width:130px;text-align:center;margin-right:40px}.seatreg-tabs-content .border-box{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.seatreg-tabs-content .action-select{float:right}.seatreg-tabs-content .action-select label{margin-left:10px;display:inline-flex;align-items:center}.seatreg-tabs-content .show-more-info{margin-right:16px}.seatreg-tabs-content .differentBgColor{background-color:#f2f2f2}.seatreg-tabs-content .manager-box{display:inline-block}.seatreg-tabs-content .reg-seat-item .booking-id-box{min-width:340px}.seatreg-tabs-content .manager-box-link:hover{cursor:pointer}.seatreg-tabs-content .seat-date-label{margin-right:60px}.seatreg-tabs-content .reg-name{font-size:30px;word-wrap:break-word}.seatreg-tabs-content .account-status{text-align:right;margin-top:10px;margin-bottom:-50px;font-weight:600}.seatreg-tabs-content .more-info{display:none;padding-top:10px}.seatreg-tabs-content .action-control{background-color:#404040;text-align:center;width:100px;float:right;cursor:pointer;color:#fff;padding:4px 0;margin-top:24px}.seatreg-settings-form .checkbox label{font-size:14px}.seatreg-tabs-content .settings-heading{margin-top:0;margin-bottom:24px}.seatreg-tabs-content .action-select .bron-action,.seatreg-tabs-content .action-select .permanent-delete-action{margin-left:4px;cursor:pointer;margin-top:0}.seatreg-tabs-content .action-label{cursor:pointer}.seatreg-tabs-content .reg-section-buttons{width:160px;float:left}.seatreg-tabs-content .admin-right-side{width:900px;margin-right:5px;float:right;position:relative;background-color:#fff}.seatreg-tabs-content .notify-text{text-align:center;margin-top:24px;font-size:20px}.seatreg-tabs-content .action-select label{margin-bottom:0}.seatreg-delete-registration-form .delete-registration-btn,.seatreg-delete-registration-form .delete-registration-btn:active,.seatreg-delete-registration-form .delete-registration-btn:focus,.seatreg-delete-registration-form .delete-registration-btn:hover{padding:24px;min-height:auto;line-height:normal;border:1px solid #ccc;box-shadow:none;background:#fff;font-size:16px;color:red}.seatreg-delete-registration-form .delete-registration-btn:hover{box-shadow:1px 1px 10px 0 rgba(204,204,204,.52)}.change-name-wrap{margin-bottom:8px}.seatreg-tabs-content .f-pic{width:41px;height:41px;background:url(sprites.png) no-repeat}.seatreg-tabs-content .a-build-btn{margin:0;padding:0;border:0}.seatreg-tabs-content .del-reg{margin:20px 0 0;padding:0;border:0;display:block;background-color:#404040;color:#fff;height:40px;width:160px}.seatreg-tabs-content .del-reg:hover{color:red}.seatreg-tabs-content .del-reg:focus{outline:0}.seatreg-tabs-content .btn-style{background-color:#404040;color:#fff;width:160px;height:40px;line-height:40px;text-align:center;cursor:pointer}.seatreg-tabs-content .a-opt-btn,.seatreg-tabs-content .adr-btn{margin:4px;padding:4px;width:140px;height:54px;line-height:42px}.seatreg-tabs-content .btn-style-active{background-color:#fff;color:#000;text-transform:uppercase;font-weight:700}.seatreg-tabs-content .a-build-btn .f-pic{float:left;background-position:-3px -336px}.seatreg-tabs-content .a-manage-btn,.seatreg-tabs-content .a-stats-btn{border-bottom:1px solid #e1e5e7}.seatreg-tabs-content .a-manage-btn .f-pic{float:left;background-position:-52px -335px}.seatreg-tabs-content .adr-btn .f-pic{float:left;background-position:-105px -334px}.seatreg-tabs-content .option-box{margin-top:20px;padding-bottom:20px;border-bottom:1px solid #000}.seatreg-tabs-content .setting-box{width:98%;margin:0 auto;padding:0 1%;border-top:1px solid #000}.seatreg-tabs-content .a-opt-btn .f-pic{float:left;background-position:-154px -332px}.seatreg-tabs-content .del-reg-form{text-align:center}.seatreg-tabs-content .del-reg-form:active,.seatreg-tabs-content .del-reg-form:focus{border:none}.seatreg-tabs-content .del-reg .f-pic{float:left;background-position:-203px -331px}.seatreg-tabs-content .a-options-btn{border-bottom:1px solid #e1e5e7}.seatreg-tabs-content .info-box{margin-bottom:20px}.seatreg-tabs-content .option-checkbox{width:20px;height:20px;vertical-align:middle;margin:0!important}.seatreg-tabs-content .select-radio-create{display:none}.seatreg-tabs-content .remove-sel-item{vertical-align:middle}.seatreg-tabs-content .custom-container{display:flex;align-items:center;flex-wrap:nowrap;column-gap:6px;margin-bottom:4px;margin-left:24px;border:1px solid #ccc;border-radius:4px;padding:12px 18px}.seatreg-tabs-content .custom-container label{margin-bottom:0;display:flex;align-items:center;flex:1 1 auto;min-width:0}.seatreg-tabs-content .custom-container label input[type=text],.seatreg-tabs-content .custom-container label select{flex:1 1 auto;min-width:40px;width:auto}.seatreg-tabs-content .custom-container .custom-container-controls{display:flex;align-items:center;flex:0 0 auto;column-gap:4px;margin-left:auto}.seatreg-tabs-content .custom-container .l-text{display:inline-block;min-width:76px;max-width:76px;overflow:hidden;text-overflow:ellipsis}.seatreg-tabs-content .custom-container-move{border:1px solid #ccc;border-radius:4px;padding:2px;cursor:pointer}.seatreg-tabs-content .custom-container-move:hover{background-color:#ccc}.seatreg-tabs-content .custom-container-move-highlight{background-color:#ee0}.seatreg-tabs-content .existing-custom-fields{margin-left:24px}.seatreg-tabs-content .payment-configuration{margin-top:12px;margin-left:24px}#paypal-webhook-check-result:not(:empty),#stripe-webhook-check-result:not(:empty){margin-top:12px}.webhook-check-list{margin:0;padding:0;list-style:none}.webhook-check-list li{margin-bottom:4px}.webhook-check-list .webhook-check-ok{color:#46b450}.webhook-check-list .webhook-check-failed{color:#dc3232}.webhook-check-list .webhook-check-detail{color:#666;word-break:break-all}.seatreg-tabs-content .custom-container input[type=checkbox]{margin-top:0}.seatreg-tabs-content .remove-cust-item{cursor:pointer;color:red;margin-left:6px}.seatreg-tabs-content .cust-field-create{margin-top:10px;margin-left:24px}.seatreg-tabs-content .select-radio-create{margin-bottom:12px}.seatreg-tabs-content .seatreg-settings-form input[type=number],.seatreg-tabs-content .seatreg-settings-form input[type=text]{height:32px;font-size:14px}.seatreg-tabs-content .cust-field-create label,.seatreg-tabs-content .seatreg-settings-form textarea{font-size:14px}.seatreg-tabs-content .cust-field-create .btn{margin-bottom:.5rem}.seatreg-tabs-content .select-option{margin-bottom:6px}.seatreg-tabs-content .cust-input-label{margin-right:10px;width:140px}.seatreg-tabs-content .custom-field-select{margin-right:10px}.seatreg-tabs-content .manager-search-wrap{width:200px;margin-top:6px;float:right}.seatreg-tabs-content .manager-search{border-color:#ccc;border-right:0;height:calc(1.5rem + .75rem + 2px);min-height:calc(1.5rem + .75rem + 2px)}.seatreg-tabs-content .manager-search:focus{box-shadow:none;border-color:#ccc;border-right:0}.seatreg-tabs-content .option-input{width:170px;margin:10px 10px 20px 0;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.seatreg-tabs-content .option-label{font-size:16px}.seatreg-tabs-content .l-text{margin-right:10px;font-size:14px}.seatreg-tabs-content .edit-btn{cursor:pointer}.seatreg-tabs-content .create-new-registration-wrapper{margin-top:20px;margin-bottom:20px;font-weight:700}.seatreg-tabs-content .admin-btn-from{border-bottom:1px solid #e1e5e7}.seatreg-tabs-content .file-type-link{float:right;margin-top:10px;margin-right:20px;font-size:18px;color:#000}.seatreg-map-popup-btn{color:#428bca;font-size:14px}.seatreg-delete-btn,.seatreg-map-popup-btn{padding:0}.seatreg_page_seatreg-management .booking-status-check-wrap input[type=checkbox]{margin-top:0;margin-left:6px}.seatreg-wp-admin .search-button{border-top-left-radius:0;border-bottom-left-radius:0}.seatreg-wp-admin .payment-log-wrap{display:grid;grid-gap:10px;grid-template-columns:minmax(40px,auto) 140px 1fr;color:#228b22}.seatreg-wp-admin .payment-log-wrap .error-log{color:red}.seatreg-wp-admin .payment-log-wrap .info-log{color:#00f}.seatreg-wp-admin .add-payment-log-wrap{display:flex;align-items:center;margin-top:12px}.seatreg-wp-admin .add-payment-log-wrap input,.seatreg-wp-admin .add-payment-log-wrap select{margin-right:12px}@media screen and (max-width:1199px){.seatreg-tabs-content #my-regs{width:970px;padding:0 15px}.seatreg-tabs-content .admin-right-side{width:700px;margin-right:5px}.seatreg-tabs-content .action-select{margin-top:10px;text-align:right;float:right}.seatreg-tabs-content .bg-color{padding-top:80px;background-color:#f2f2f2}}@media screen and (max-width:800px){.seatreg-tabs-content .manager-box{display:block;text-align:left}.seatreg-tabs-content .file-type-link{position:absolute;top:0;margin:0}.seatreg-tabs-content .pdf-link{right:0}.seatreg-tabs-content .text-link{right:150px}.seatreg-tabs-content .xlsx-link{right:70px}.seatreg-tabs-content .manager-search-wrap{margin-top:40px}.seatreg-tabs-content .action-select{float:none;text-align:right;display:block;margin-top:10px}}@media screen and (max-width:992px){.seatreg-tabs-content .reg-section-buttons{width:20%}.seatreg-tabs-content #my-regs{width:auto}.seatreg-tabs-content .admin-right-side{width:70%;margin:0}.seatreg-tabs-content #alertify{top:30%}}@media screen and (max-width:776px){.seatreg-tabs-content .reg-section-buttons{width:25%}.seatreg-tabs-content .admin-btn-from,.seatreg-tabs-content .btn-style,.seatreg-tabs-content .del-reg,.seatreg-tabs-content .del-reg-form{width:100%;margin-bottom:4px}.seatreg-tabs-content .account-status{margin-bottom:0}.seatreg-tabs-content .first-reg-section .tab_container:before{margin-top:-300px;height:300px}.seatreg-tabs-content .tab_container:before{margin-top:-310px;height:310px}.seatreg-tabs-content .tab a{padding:0}}@media screen and (max-width:900px){.seatreg-tabs-content .first-reg-section .tab_container:before{margin-top:-330px;height:330px}.seatreg-tabs-content .tab_container:before{margin-top:-250px;height:250px}}@media screen and (max-width:500px){.seatreg-tabs-content .bg-color{padding-top:100px;background-color:#f2f2f2}.seatreg-tabs-content .reg-section-buttons{font-size:12px}.seatreg-tabs-content .first-reg-section .tab_container:before,.seatreg-tabs-content .tab_container:before{margin-top:-330px;height:330px}.seatreg-tabs-content .custom-container input[type=text]{width:60px}}#calendar-dates-list .calendar-date-chip{display:inline-flex;align-items:center;margin:2px 4px 2px 0;padding:2px 4px 2px 8px;background-color:#e7f3ff;border:1px solid #b8daff;border-radius:3px;font-size:12px;color:#04357d}#calendar-dates-list .calendar-date-chip-remove{margin-left:6px;padding:0 3px;border:none;background:0 0;color:#04357d;font-size:14px;line-height:1;cursor:pointer;opacity:.7}#calendar-dates-list .calendar-date-chip-remove:hover{opacity:1;color:#c00}
  • seatreg/trunk/js/build.js

    r3634058 r3693621  
    526526                this.needToSave = false;  //if user makes changes this will be true. when saved this will be false
    527527                this.roomNameChange = {};  //if room name got changed. store old and new here
    528                 this.usingSeats = true; //do we use seats or generic place
    529528                this.settings = {};
    530529                this.hasCustomPayments = false; //does registration have custom payments (new ones, not legacy)
    … …  
    589588                                var $imgWrap = $("<div class='uploaded-image-box'></div");
    590589                                $imgWrap.append("<img src='" + window.WP_Seatreg.uploads_url + "/room_images/" + window.seatreg.selectedRegistration + "/" + uploaded.file + "' class='uploaded-image' />");
    591                                 $imgWrap.append("<span class='add-img-room' data-img='"+ uploaded.file +"' data-size='" + uploaded.size[0] + "," + uploaded.size[1] + "'><span class='glyphicon glyphicon-ok' aria-hidden='true'></span>"+ translator.translate('addToRoomBackground') +"</span>");
     590                                $imgWrap.append("<span class='add-img-room' data-img='"+ uploaded.file +"' data-size='" + uploaded.size[0] + "," + uploaded.size[1] + "'><span class='glyphicon glyphicon-ok' aria-hidden='true'></span>"+ seatregFormat(translator.translate('addToRoomBackground'), [seatregRoomNouns().singular]) +"</span>");
    592591                                $imgWrap.append("<span class='up-img-rem' data-img='"+ uploaded.file +"'><span class='glyphicon glyphicon-remove' aria-hidden='true'></span> "+ translator.translate('remove') +"</span>");
    593592
    … …  
    817816                                                'background-color':'yellow',
    818817                                        }).addClass('legend-box-circle');
    819                                         textSpan.text(this.using_seats ? translator.translate('pendingSeat') : translator.translate('pendingPlace'));
     818                                        textSpan.text(seatregFormat(translator.translate('pendingSeat'), [seatregSeatNouns().singular]));
    820819                                        break;
    821820
    822821                                case 1:
    823822                                        colorBox.css('background-color','red').addClass('legend-box-circle');
    824                                         textSpan.text(this.using_seats ? translator.translate('confirmedSeat') : translator.translate('confirmedPlace'));
     823                                        textSpan.text(seatregFormat(translator.translate('confirmedSeat'), [seatregSeatNouns().singular]));
    825824                                        break;
    826825                        }
    … …  
    967966                this.rooms[this.roomLocator] = new Room(
    968967                        this.roomLocator,
    969                         this.roomLocator + ' ' + translator.translate('room'),
     968                        this.roomLocator + ' ' + seatregRoomNouns().singular,
    970969                        uuid
    971970                );
    … …  
    10381037               
    10391038                if(size == 1) {
    1040                         alert(translator.translate('oneRoomNeeded'));
     1039                        alert(seatregFormat(translator.translate('oneRoomNeeded'), [seatregRoomNouns().singular]));
    10411040                }else if(size > 1) {
    10421041                        let roomDeletedLocation = this.currentRoom;
    … …  
    12031202                                buttonFocus: "ok" 
    12041203                        });
    1205                         alertify.alert(translator.translate('alreadyInRoom'));
     1204                        alertify.alert(seatregFormat(translator.translate('alreadyInRoom'), [seatregRoomNouns().singular]));
    12061205                }
    12071206        };
    … …  
    22012200                                                buttonFocus: "ok" 
    22022201                                        });
    2203                                 alertify.alert(translator.translate('allRoomsNeedName'));
     2202                                alertify.alert(seatregFormat(translator.translate('allRoomsNeedName'), [seatregRoomNouns().plural]));
    22042203
    22052204                                return false;
    … …  
    23352334                }else {
    23362335                        this.settings = window.seatreg.settings;
    2337                         this.usingSeats = window.seatreg.settings.using_seats === '1';
    23382336                        this.hasCustomPayments = window.seatreg.settings.custom_payments !== '[]' && window.seatreg.settings.custom_payments !== null;
    23392337
    … …  
    26972695                        $('#set-seat-locks').addClass('d-none');
    26982696                        $lockWrap.append(
    2699                                 '<div class="alert alert-primary">'+ translator.translate('noSeatsSelected') +'</div>'
     2697                                '<div class="alert alert-primary">'+ seatregFormat(translator.translate('noSeatsSelected'), [seatregSeatNouns().plural]) +'</div>'
    27002698                        );
    27012699                }else if(selectedBoxes.length == 1) {
    … …  
    27142712                                        '<div class="lock-item" data-box-location="' + boxLocation + '">' +
    27152713                                                '<div class="lock-item-seat">'  + box.seat  + '</div>' +
    2716                                                 '<label>' + translator.translate('lockSeat') +
     2714                                                '<label>' + seatregFormat(translator.translate('lockSeat'), [seatregSeatNouns().singular]) +
    27172715                                                        '<input type="checkbox" ' + (box.lock ? "checked" : "") + ' />' +
    27182716                                                '</label>' +
    … …  
    27492747                        $('#set-prices').addClass('d-none');
    27502748                        $pricingWrap.append(
    2751                                 '<div class="alert alert-primary">'+ translator.translate('noSeatsSelected') +'</div>'
     2749                                '<div class="alert alert-primary">'+ seatregFormat(translator.translate('noSeatsSelected'), [seatregSeatNouns().plural]) +'</div>'
    27522750                        );
    27532751                }else if(selectedBoxes.length == 1) {
    … …  
    33923390                        });
    33933391
    3394                         alertify.confirm(translator.translate('deleteRoom_') + reg.rooms[reg.currentRoom].title + " ?", function (e) {
     3392                        alertify.confirm(seatregFormat(translator.translate('deleteRoomConfirm'), [seatregRoomNouns().singular, reg.rooms[reg.currentRoom].title]), function (e) {
    33953393                            if (e) {
    33963394                                reg.deleteCurrentRoom();
    … …  
    34073405                        });
    34083406
    3409                         alertify.alert(translator.translate('cantDelRoom_') +'<span class="bold-text">' + reg.rooms[reg.currentRoom].title + '</span>' + translator.translate('_cantDelRoomBecause'));
     3407                        alertify.alert(seatregFormat(translator.translate('cantDeleteRoom'), [seatregRoomNouns().singular, '<span class="bold-text">' + reg.rooms[reg.currentRoom].title + '</span>']));
    34103408                }
    34113409        });
    … …  
    35253523                if($('#room-name-dialog-input').val() == '') {
    35263524                        $('#room-name-dialog-input').focus();
    3527                         $('.room-name-error').text(translator.translate('roomNameMissing')).css('display','block');
     3525                        $('.room-name-error').text(seatregFormat(translator.translate('roomNameMissing'), [seatregRoomNouns().singularUpper])).css('display','block');
    35283526                }else {
    35293527                        if(!reg.roomNameExists($('#room-name-dialog-input').val())) {
    … …  
    35393537                                        reg.roomNameChange[initName] = newRoom;
    35403538
    3541                                         alertify.success(translator.translate('roomNameChanged'));
     3539                                        alertify.success(seatregFormat(translator.translate('roomNameChanged'), [seatregRoomNouns().singularUpper]));
    35423540                                }else {
    35433541                                        if(reg.rooms[reg.currentRoom].initialName == "") {
    35443542                                                reg.rooms[reg.currentRoom].initialName = reg.rooms[reg.currentRoom].title;
    35453543                                        }
    3546                                         alertify.success(translator.translate('roomNameSet'));
     3544                                        alertify.success(seatregFormat(translator.translate('roomNameSet'), [seatregRoomNouns().singular]));
    35473545                                }
    35483546                               
    … …  
    35513549                               
    35523550                        }else {
    3553                                 $('.room-name-error').text(translator.translate('roomNameExists')).css('display','block');
     3551                                $('.room-name-error').text(seatregFormat(translator.translate('roomNameExists'), [seatregRoomNouns().singularUpper])).css('display','block');
    35543552                        }
    35553553                }
    … …  
    35703568
    35713569                reg.rooms[reg.currentRoom].description = roomDescription;
    3572                 alertify.success(translator.translate('roomDescriptionSet'));
     3570                alertify.success(seatregFormat(translator.translate('roomDescriptionSet'), [seatregRoomNouns().singularUpper]));
    35733571                $('#room-description-dialog').modal('toggle');
    35743572    });
    … …  
    36673665                                        if(reg.rooms[reg.currentRoom].backgroundImage === imgName) {
    36683666                                                reg.removeCurrentRoomImage();
    3669                                                 $('#activ-room-img-wrap').empty().text(translator.translate('noBgImageInRoom'));
     3667                                                $('#activ-room-img-wrap').empty().text(seatregFormat(translator.translate('noBgImageInRoom'), [seatregRoomNouns().singular]));
    36703668                                        }
    36713669                                       
    … …  
    36823680                var curImgWrap = $('<div class="cur-img-wrap"></div>');
    36833681                var bgImg = $('<img class="uploaded-image" src="' + window.WP_Seatreg.uploads_url + '/room_images/' + seatreg.selectedRegistration + '/' + reg.rooms[reg.currentRoom].backgroundImage + '" />');
    3684                 var remImg = $('<span id="rem-room-img"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> '+ translator.translate('removeFromRoom') +'</span>');
     3682                var remImg = $('<span id="rem-room-img"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> '+ seatregFormat(translator.translate('removeFromRoom'), [seatregRoomNouns().singular]) +'</span>');
    36853683
    36863684                curImgWrap.append(bgImg, remImg);
    … …  
    36953693                        var curImgWrap = $('<div class="cur-img-wrap"></div>');
    36963694                        var bgImg = $('<img class="uploaded-image" src="'+ window.WP_Seatreg.uploads_url + '/room_images/' + seatreg.selectedRegistration + '/' + reg.rooms[reg.currentRoom].backgroundImage + '" />');
    3697                         var remImg = $('<span id="rem-room-img"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> '+ translator.translate('removeFromRoom') +'</span>');
     3695                        var remImg = $('<span id="rem-room-img"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> '+ seatregFormat(translator.translate('removeFromRoom'), [seatregRoomNouns().singular]) +'</span>');
    36983696
    36993697                        curImgWrap.append(bgImg, remImg);
    37003698                        $('#activ-room-img-wrap').append(curImgWrap);
    37013699                }else {
    3702                         $('#activ-room-img-wrap').html(translator.translate('noBgImageInRoom'));
     3700                        $('#activ-room-img-wrap').html(seatregFormat(translator.translate('noBgImageInRoom'), [seatregRoomNouns().singular]));
    37033701                }
    37043702        });
    … …  
    37083706                $('.room-image').remove();
    37093707                $(this).closest('.cur-img-wrap').remove();
    3710                 $('#activ-room-img-wrap').html(translator.translate('noBgImageInRoom'));
     3708                $('#activ-room-img-wrap').html(seatregFormat(translator.translate('noBgImageInRoom'), [seatregRoomNouns().singular]));
    37113709        });
    37123710       
  • seatreg/trunk/js/seatreg_admin.js

    r3680221 r3693621  
    11(function($) {
    2         var canvasSupport = ($('html').hasClass('no-canvas') ? false : true);
    32        var bookingOrderInManager = null;
    43        var bookingManagerActiveAddBookingIdLookupIndex = 0;
    … …  
    4039        };
    4140
    42         $('.time-stamp').each(function() {
    43                 $(this).text(timeStampToDateString($(this).text()));
    44         });
    45 
    4641        function seaterg_admin_ajax(action, code, data) {
    4742                return $.ajax({
    … …  
    182177        }
    183178
    184         function timeStampToDateString(timeStampText) {
    185                 if(!isNaN(timeStampText)) {
    186                         var date = new Date(parseInt(timeStampText));
    187 
    188                         return date.format("d.M.Y H:i");
    189                 }
    190                
    191                 return timeStampText;
    192         }
    193 
    194179        function generateUniqueString() {
    195180                const timestamp = new Date().getTime().toString(36);
    … …  
    255240                                }
    256241                                $('.reg-title-name').text(registrationName);
    257                                
     242
     243                                window.seatreg.selectedRegistration = code;
     244                                window.seatreg.settings = {
     245                                        paypal_payments: data._response.data.registration[0].paypal_payments,
     246                                        paypal_rest_payments: data._response.data.registration[0].paypal_rest_payments,
     247                                        stripe_payments: data._response.data.registration[0].stripe_payments,
     248                                        custom_payment: data._response.data.registration[0].custom_payment,
     249                                        using_seats: data._response.data.registration[0].using_seats
     250                                };
     251                                window.seatreg.roomNouns = data._response.data.roomNouns;
     252                                window.seatreg.seatNouns = data._response.data.seatNouns;
     253                                seatregApplyNouns();
     254
    258255                                if(data._response.data.registration[0].registration_layout == null) {
    259                                         window.seatreg.selectedRegistration = code;                             
    260256                                        $('.seatreg-builder-popup').css({'display': 'block'});
    261257                                        window.seatreg.builder.syncData(null);
    262258                                }else {
    263                                         window.seatreg.selectedRegistration = code;
    264                                         window.seatreg.settings = {
    265                                                 paypal_payments: data._response.data.registration[0].paypal_payments,
    266                                                 paypal_rest_payments: data._response.data.registration[0].paypal_rest_payments,
    267                                                 stripe_payments: data._response.data.registration[0].stripe_payments,
    268                                                 custom_payment: data._response.data.registration[0].custom_payment,
    269                                                 using_seats: data._response.data.registration[0].using_seats
    270                                         };
    271                                
    272259                                        $('.seatreg-builder-popup').css({'display': 'block'});
    273260                                        window.seatreg.builder.syncData( $.parseJSON(data._response.data.registration[0].registration_layout) );
    … …  
    357344                dateFormat: 'yy-mm-dd',
    358345                onSelect: function(dateText) {
    359                         $('#overview-calendar-date').val( seatregFormatCalendarDateForDisplay(dateText, WP_Seatreg.SITE_LANGUAGE) );
    360                         $('#existing-regs .room-list-item[data-active="true"]').trigger('click');
     346                        setCalendarDateUrlParam(dateText);
     347                        $('#overview-calendar-date').val( seatregFormatCalendarDateForDisplay(dateText, WP_Seatreg.SEATREG_SITE_LANGUAGE) );
     348                        alertify.success(translator.translate('reloadingPage'));
     349                        location.reload();
    361350                }
    362351        });
    … …  
    365354    if (initialInternal) {
    366355        $('#overview-calendar-date').val(
    367             seatregFormatCalendarDateForDisplay(initialInternal, WP_Seatreg.SITE_LANGUAGE)
     356            seatregFormatCalendarDateForDisplay(initialInternal, WP_Seatreg.SEATREG_SITE_LANGUAGE)
    368357        );
    369358    }
    370359}
    371360initOverviewCalendarDatePicker();
     361
     362var seatregOverviewChartColors = {
     363        confirmed: '#2e7d32',
     364        pending: '#dba617',
     365        open: '#2271b1'
     366};
     367
     368//Column and bar are the same Chart.js type, told apart by which axis the categories run along
     369var seatregOverviewChartTypes = {
     370        doughnut: { type: 'doughnut' },
     371        pie: { type: 'pie' },
     372        column: { type: 'bar', indexAxis: 'x' },
     373        bar: { type: 'bar', indexAxis: 'y' }
     374};
     375
     376function seatregOverviewChartConfig(canvas, chartType) {
     377        var shape = seatregOverviewChartTypes[chartType] || seatregOverviewChartTypes.doughnut;
     378        var isBar = shape.type === 'bar';
     379        var values = ['confirmed', 'pending', 'open'].map(function(part) {
     380                return parseInt($(canvas).attr('data-' + part), 10) || 0;
     381        });
     382
     383        return {
     384                type: shape.type,
     385                data: {
     386                        labels: [
     387                                translator.translate('overviewConfirmed'),
     388                                translator.translate('overviewPending'),
     389                                translator.translate('overviewOpen')
     390                        ],
     391                        datasets: [{
     392                                data: values,
     393                                backgroundColor: [
     394                                        seatregOverviewChartColors.confirmed,
     395                                        seatregOverviewChartColors.pending,
     396                                        seatregOverviewChartColors.open
     397                                ],
     398                                borderWidth: isBar ? 0 : 2,
     399                                borderColor: '#fff'
     400                        }]
     401                },
     402                options: {
     403                        indexAxis: shape.indexAxis,
     404                        responsive: true,
     405                        maintainAspectRatio: false,
     406                        animation: false,
     407                        //The screen has its own legend beside the chart, with the percentages Chart.js does not show
     408                        plugins: { legend: { display: false } },
     409                        scales: isBar ? {
     410                                x: { beginAtZero: true, ticks: { precision: 0 }, grid: { display: shape.indexAxis === 'y' } },
     411                                y: { beginAtZero: true, ticks: { precision: 0 }, grid: { display: shape.indexAxis === 'x' } }
     412                        } : {}
     413                }
     414        };
     415}
     416
     417//Every room's numbers are rendered up front, so switching is only a matter of which panel is shown.
     418//A chart is drawn the first time its panel is shown, because Chart.js cannot size a hidden canvas
     419function initOverviewRoomTabs() {
     420        var $tabs = $('.seatreg-overview__rooms [role="tab"]');
     421
     422        if( $tabs.length === 0 ) {
     423                return;
     424        }
     425
     426        var charts = {};
     427        var chartType = $('.seatreg-overview__chart-type[aria-pressed="true"]').first().attr('data-chart-type') || 'doughnut';
     428
     429        function drawChart($panel) {
     430                var canvas = $panel.find('.seatreg-overview__canvas').get(0);
     431
     432                if( !canvas || typeof Chart === 'undefined' ) {
     433                        return;
     434                }
     435
     436                var panelId = $panel.attr('id');
     437
     438                if( charts[panelId] ) {
     439                        charts[panelId].resize();
     440
     441                        return;
     442                }
     443
     444                charts[panelId] = new Chart(canvas.getContext('2d'), seatregOverviewChartConfig(canvas, chartType));
     445        }
     446
     447        function selectTab($tab, moveFocus) {
     448                $tabs.attr('aria-selected', 'false').attr('tabindex', '-1');
     449                $('.seatreg-overview__panel').prop('hidden', true);
     450
     451                $tab.attr('aria-selected', 'true').attr('tabindex', '0');
     452
     453                var $panel = $('#' + $tab.attr('aria-controls'));
     454                $panel.prop('hidden', false);
     455                drawChart($panel);
     456
     457                if( moveFocus ) {
     458                        $tab.trigger('focus');
     459                }
     460        }
     461
     462        $tabs.on('click', function() {
     463                selectTab($(this), false);
     464        });
     465
     466        $tabs.on('keydown', function(event) {
     467                var index = $tabs.index(this);
     468                var nextIndex = null;
     469
     470                switch(event.key) {
     471                        case 'ArrowDown':
     472                        case 'ArrowRight':
     473                                nextIndex = (index + 1) % $tabs.length;
     474                                break;
     475                        case 'ArrowUp':
     476                        case 'ArrowLeft':
     477                                nextIndex = (index - 1 + $tabs.length) % $tabs.length;
     478                                break;
     479                        case 'Home':
     480                                nextIndex = 0;
     481                                break;
     482                        case 'End':
     483                                nextIndex = $tabs.length - 1;
     484                                break;
     485                        default:
     486                                return;
     487                }
     488
     489                event.preventDefault();
     490                selectTab($tabs.eq(nextIndex), true);
     491        });
     492
     493        //Every panel carries its own set of buttons, so the pressed one is kept in step across all of them
     494        $('.seatreg-overview__panels').on('click', '.seatreg-overview__chart-type', function() {
     495                var picked = $(this).attr('data-chart-type');
     496
     497                if( picked === chartType ) {
     498                        return;
     499                }
     500
     501                chartType = picked;
     502
     503                $('.seatreg-overview__chart-type').each(function() {
     504                        $(this).attr('aria-pressed', $(this).attr('data-chart-type') === chartType ? 'true' : 'false');
     505                });
     506
     507                Object.keys(charts).forEach(function(panelId) {
     508                        charts[panelId].destroy();
     509                        delete charts[panelId];
     510                });
     511
     512                drawChart($('.seatreg-overview__panel:not([hidden])'));
     513        });
     514
     515        drawChart($('.seatreg-overview__panel:not([hidden])'));
     516}
     517
     518//Chart.js is enqueued on this screen only, so wait for every footer script to have run
     519$(function() {
     520        initOverviewRoomTabs();
     521});
    372522
    373523function initBookingManagerCalendarDatePicer() {
    … …  
    378528                onSelect: function(dateText) {
    379529                        setCalendarDateUrlParam(dateText);
    380                         $('#booking-manager-calendar-date').val( seatregFormatCalendarDateForDisplay(dateText, WP_Seatreg.SITE_LANGUAGE) );
     530                        $('#booking-manager-calendar-date').val( seatregFormatCalendarDateForDisplay(dateText, WP_Seatreg.SEATREG_SITE_LANGUAGE) );
    381531                        alertify.success(translator.translate('reloadingPage'));
    382532                        location.reload();
    … …  
    386536    if (initialInternal) {
    387537        $('#booking-manager-calendar-date').val(
    388             seatregFormatCalendarDateForDisplay(initialInternal, WP_Seatreg.SITE_LANGUAGE)
     538            seatregFormatCalendarDateForDisplay(initialInternal, WP_Seatreg.SEATREG_SITE_LANGUAGE)
    389539        );
    390540    }
    … …  
    477627                window.history.replaceState(null, '', '#' + targetPanel.attr('id'));
    478628        }
    479 });
    480 
    481 $('#existing-regs-wrap').on('click', '.room-list-item', function() {
    482         var code = $('#seatreg-reg-code').val();
    483         var target = $(this).attr('data-stats-target');
    484         var calendarDate = $('#overview-calendar-date-value').val() || null;
    485         var overViewContainer = $(this).closest('.reg-overview');
    486         overViewContainer.append($('<img>').attr('src', WP_Seatreg.plugin_dir_url + 'img/ajax_loader.gif').addClass('ajax_loader'));
    487 
    488         var promise = seaterg_admin_ajax2('seatreg_get_room_stats', code, {
    489                 target: target,
    490                 calendarDate: calendarDate
    491         });
    492 
    493         promise.done(function(data) {
    494                 overViewContainer.replaceWith(data).promise().done(function() {
    495                         $('#existing-regs-wrap .reg-overview').find('.time-stamp').each(function() {
    496                                 $(this).text(timeStampToDateString($(this).text()));
    497                         });
    498 
    499                         var donutWrapper = $('#existing-regs-wrap').find('.reg-overview-donuts');               
    500                         var doughnutData = [
    501                                 {
    502                                         value: parseInt(donutWrapper.find('.seats-open-don').val()),
    503                                         color:"#61B329"
    504                                 },
    505                                 {
    506                                         value : parseInt(donutWrapper.find('.seats-bron-don').val()),
    507                                         color : "#FFFF00"
    508                                 },
    509                                 {
    510                                         value : parseInt(donutWrapper.find('.seats-taken-don').val()),
    511                                         color : "red"
    512                                 }
    513                        
    514                         ];
    515 
    516                         if( canvasSupport) {
    517                                 var ctx = donutWrapper.find('.stats-doughnut').get(0).getContext("2d");
    518                                 var myNewChart = new Chart(ctx).Doughnut(doughnutData,{animation: false});
    519                         }
    520 
    521                 });
    522                 initOverviewCalendarDatePicker();
    523                
    524         });
    525         promise.fail = seatreg_admin_ajax_error;
    526 });
    527 
    528 $('.reg-overview-donuts').each(function() {
    529         var donutWrapper = $(this);
    530         var doughnutData = [
    531                 {
    532                         value: parseInt(donutWrapper.find('.seats-open-don').val()),
    533                         color:"#61B329"
    534                 },
    535                 {
    536                         value : parseInt(donutWrapper.find('.seats-bron-don').val()),
    537                         color : "#FFFF00"
    538                 },
    539                 {
    540                         value : parseInt(donutWrapper.find('.seats-taken-don').val()),
    541                         color : "red"
    542                 }
    543        
    544         ];
    545 
    546         if(canvasSupport) {
    547                 var ctx = donutWrapper.find('.stats-doughnut').get(0).getContext("2d");
    548                 var myNewChart = new Chart(ctx).Doughnut(doughnutData,{animation: false});
    549         }                       
    550629});
    551630
    … …  
    11531232        $bookingWrap.append('<div><b>Name: </b>' + bookingData.first_name + ',</div>');
    11541233        $bookingWrap.append('<div>' + bookingData.last_name + ',</div>');
    1155         $bookingWrap.append('<div><b>Seat: </b>' + bookingData.seat_nr + '</div>');
     1234        $bookingWrap.append('<div><b>' + seatregSeatNouns().singularUpper + ': </b>' + bookingData.seat_nr + '</div>');
    11561235
    11571236        if(validationData.room_name) {
    1158                 $bookingWrap.append('<div><b>Room: </b>' + validationData.room_name + '</div>');
     1237                $bookingWrap.append('<div><b>' + seatregRoomNouns().singularUpper + ': </b>' + validationData.room_name + '</div>');
    11591238        }
    11601239
    … …  
    13051384                        '<label for="booker-email-change-field"><h5>' +
    13061385                                translator.translate('bookingMainEmail') +
    1307                         '</h5></label> <i class="fa fa-question-circle seatreg-ui-tooltip" aria-hidden="true" title="' + translator.translate('multiBookingMailEmailEditDesc') + '"></i><br>' +
     1386                        '</h5></label> <i class="fa fa-question-circle seatreg-ui-tooltip" aria-hidden="true" title="' + seatregFormat(translator.translate('multiBookingMailEmailEditDesc'), [seatregSeatNouns().singular]) + '"></i><br>' +
    13081387                        '<input type="email" id="booker-email-change-field" name="booker-email" class="modal-email-input" value="'+ info.data('booker-email') +'" />'
    13091388                );
    … …  
    15061585
    15071586                        if(data.status === 'room-searching') {
    1508                                 $('#add-booking-modal-form .modal-body-item').eq(data.index).find('[name="room[]"]').closest('.add-modal-input-wrap').find('.input-error').text(translator.translate('roomNotExist'));
    1509                                 alertify.error(translator.translate('roomNotExist'));
     1587                                $('#add-booking-modal-form .modal-body-item').eq(data.index).find('[name="room[]"]').closest('.add-modal-input-wrap').find('.input-error').text(seatregFormat(translator.translate('roomNotExist'), [seatregRoomNouns().singularUpper]));
     1588                                alertify.error(seatregFormat(translator.translate('roomNotExist'), [seatregRoomNouns().singularUpper]));
    15101589                        }
    15111590                        if(data.status === 'seat-id-searching') {
    1512                                 $('#add-booking-modal-form .modal-body-item').eq(data.index).find('[name="seat-id[]"]').closest('.add-modal-input-wrap').find('.input-error').text(translator.translate('seatIdNotExist'));
    1513                                 alertify.error(translator.translate('seatIdNotExist'));
     1591                                $('#add-booking-modal-form .modal-body-item').eq(data.index).find('[name="seat-id[]"]').closest('.add-modal-input-wrap').find('.input-error').text(seatregFormat(translator.translate('seatIdNotExist'), [seatregSeatNouns().singularUpper]));
     1592                                alertify.error(seatregFormat(translator.translate('seatIdNotExist'), [seatregSeatNouns().singularUpper]));
    15141593                        }
    15151594                        if(data.status === 'seat-booked') {
    1516                                 $('#add-booking-modal-form .modal-body-item').eq(data.index).find('[name="seat-id[]"]').closest('.add-modal-input-wrap').find('.input-error').text(translator.translate('seatAlreadyBookedPending'));
    1517                                 alertify.error(translator.translate('seatAlreadyBookedPending'));
     1595                                $('#add-booking-modal-form .modal-body-item').eq(data.index).find('[name="seat-id[]"]').closest('.add-modal-input-wrap').find('.input-error').text(seatregFormat(translator.translate('seatAlreadyBookedPending'), [seatregSeatNouns().singularUpper]));
     1596                                alertify.error(seatregFormat(translator.translate('seatAlreadyBookedPending'), [seatregSeatNouns().singularUpper]));
    15181597                        }
    15191598                        if(data.status === 'create failed') {
    … …  
    15281607                        }
    15291608                        if(data.status === 'duplicate-seat') {
    1530                                 alertify.error(translator.translate('duplicateSeatDetected'));
     1609                                alertify.error(seatregFormat(translator.translate('duplicateSeatDetected'), [seatregSeatNouns().singular]));
    15311610                        }
    15321611                        if(data.status === 'seat-price-not-found') {
    … …  
    16901769                }else {
    16911770                        if(data.status == 'room-searching') {
    1692                                 $('#edit-room-error').text(translator.translate('roomNotExist'));
    1693                                 alertify.error(translator.translate('roomNotExist'));
     1771                                $('#edit-room-error').text(seatregFormat(translator.translate('roomNotExist'), [seatregRoomNouns().singularUpper]));
     1772                                alertify.error(seatregFormat(translator.translate('roomNotExist'), [seatregRoomNouns().singularUpper]));
    16941773                        }
    16951774                        if(data.status == 'seat-id-searching') {
    1696                                 $('#edit-seat-error').text(translator.translate('seatIdNotExist'));
    1697                                 alertify.error(translator.translate('seatIdNotExist'));
     1775                                $('#edit-seat-error').text(seatregFormat(translator.translate('seatIdNotExist'), [seatregSeatNouns().singularUpper]));
     1776                                alertify.error(seatregFormat(translator.translate('seatIdNotExist'), [seatregSeatNouns().singularUpper]));
    16981777                        }
    16991778                        if(data.status == 'seat-booked') {
    1700                                 $('#edit-seat-error').text(translator.translate('seatAlreadyBookedPending'));
    1701                                 alertify.error(translator.translate('seatAlreadyBookedPending'));
     1779                                $('#edit-seat-error').text(seatregFormat(translator.translate('seatAlreadyBookedPending'), [seatregSeatNouns().singularUpper]));
     1780                                alertify.error(seatregFormat(translator.translate('seatAlreadyBookedPending'), [seatregSeatNouns().singularUpper]));
    17021781                        }
    17031782                        if(data.status == 'update failed') {
    … …  
    26792758*/
    26802759
    2681 // Lightweight printf-style replace supporting %s, %d and positional %1$d, %2$s tokens.
    2682 function seatregFlowFormat(template, args) {
    2683         if (!args || !args.length) {
    2684                 return template;
    2685         }
    2686 
    2687         return template
    2688                 .replace(/%(\d+)\$[ds]/g, function(match, position) {
    2689                         return args[parseInt(position, 10) - 1];
    2690                 })
    2691                 .replace(/%[ds]/g, (function() {
    2692                         var index = 0;
    2693                         return function() {
    2694                                 return args[index++];
    2695                         };
    2696                 })());
    2697 }
    2698 
    26992760// Appends a titled, bulleted group to the summary box (skipped when it has no items).
    27002761function seatregAppendFlowGroup($box, title, items) {
    … …  
    27402801                var closeReason = ($form.find('#registration-close-reason').val() || '').trim();
    27412802                if (closeReason !== '') {
    2742                         closedText += ' ' + seatregFlowFormat(t('flowClosedReason'), [closeReason]);
     2803                        closedText += ' ' + seatregFormat(t('flowClosedReason'), [closeReason]);
    27432804                }
    27442805                $box.text(closedText);
    … …  
    27472808        }
    27482809
     2810        // The summary follows the form as it is typed, so it reads the noun fields rather than the
     2811        // saved nouns, and falls back to the checkbox the same way the server does.
     2812        var typedSingular = ($form.find('#seat-noun-singular').val() || '').trim();
     2813        var typedPlural = ($form.find('#seat-noun-plural').val() || '').trim();
     2814        var renamed = typedSingular !== '' && typedPlural !== '';
    27492815        var usingSeats = $form.find('#using-seats').is(':checked');
    2750         var nounSingular = usingSeats ? t('flowSeatSingular') : t('flowPlaceSingular');
    2751         var nounPlural = usingSeats ? t('flowSeatPlural') : t('flowPlacePlural');
     2816        var nounSingular = renamed ? typedSingular : (usingSeats ? t('flowSeatSingular') : t('flowPlaceSingular'));
     2817        var nounPlural = renamed ? typedPlural : (usingSeats ? t('flowSeatPlural') : t('flowPlacePlural'));
    27522818
    27532819        // Each item carries its sentence and the selector of the setting it describes (for the jump link).
    … …  
    27792845                var wpBookingLimit = parseInt($form.find('#wp-user-booking-limit').val(), 10);
    27802846                if (!isNaN(wpBookingLimit) && wpBookingLimit > 0) {
    2781                         beforeBooking.push(item(seatregFlowFormat(t('flowWpBookingLimit'), [wpBookingLimit, nounPlural]), '#wp-user-booking-limit'));
     2847                        beforeBooking.push(item(seatregFormat(t('flowWpBookingLimit'), [wpBookingLimit, nounPlural]), '#wp-user-booking-limit'));
    27822848                }
    27832849                var wpSeatLimit = parseInt($form.find('#wp-user-bookings-seat-limit').val(), 10);
    27842850                if (!isNaN(wpSeatLimit) && wpSeatLimit > 0) {
    2785                         beforeBooking.push(item(seatregFlowFormat(t('flowWpSeatLimit'), [wpSeatLimit, nounPlural]), '#wp-user-bookings-seat-limit'));
     2851                        beforeBooking.push(item(seatregFormat(t('flowWpSeatLimit'), [wpSeatLimit, nounPlural]), '#wp-user-bookings-seat-limit'));
    27862852                }
    27872853        }
    … …  
    28202886        var maxSeats = parseInt($form.find('#registration-max-seats').val(), 10);
    28212887        if (!isNaN(maxSeats) && maxSeats > 0) {
    2822                 makingBooking.push(item(seatregFlowFormat(t('flowSelectMax'), [nounPlural, maxSeats]), '#registration-max-seats'));
     2888                makingBooking.push(item(seatregFormat(t('flowSelectMax'), [nounPlural, maxSeats]), '#registration-max-seats'));
    28232889        } else {
    2824                 makingBooking.push(item(seatregFlowFormat(t('flowSelect'), [nounPlural]), '#using-seats'));
     2890                makingBooking.push(item(seatregFormat(t('flowSelect'), [nounPlural]), '#using-seats'));
    28252891        }
    28262892        // Booking data shown publicly on the map for already-booked seats/places.
    … …  
    28312897        });
    28322898        if (shownBookingDetails.length > 0) {
    2833                 makingBooking.push(item(seatregFlowFormat(t('flowShowBookingData'), [nounPlural, shownBookingDetails.join(', ')]), 'input[name="show-booking-data-registration[]"]'));
     2899                makingBooking.push(item(seatregFormat(t('flowShowBookingData'), [nounPlural, shownBookingDetails.join(', ')]), 'input[name="show-booking-data-registration[]"]'));
    28342900        }
    28352901        if ($form.find('#automatic-booking-confirm-dialog').is(':checked')) {
    2836                 makingBooking.push(item(seatregFlowFormat(t('flowAutoDialog'), [nounSingular]), '#automatic-booking-confirm-dialog'));
     2902                makingBooking.push(item(seatregFormat(t('flowAutoDialog'), [nounSingular]), '#automatic-booking-confirm-dialog'));
    28372903        } else {
    2838                 makingBooking.push(item(seatregFlowFormat(t('flowManualDialog'), [nounPlural]), '#automatic-booking-confirm-dialog'));
     2904                makingBooking.push(item(seatregFormat(t('flowManualDialog'), [nounPlural]), '#automatic-booking-confirm-dialog'));
    28392905        }
    28402906        // Coupons are applied in the cart (only shown when payment is enabled) before entering details.
    … …  
    28432909        }
    28442910        if ($form.find('#one-person-checkout').is(':checked')) {
    2845                 makingBooking.push(item(seatregFlowFormat(t('flowOnePersonCheckout'), [nounSingular]), '#one-person-checkout'));
     2911                makingBooking.push(item(seatregFormat(t('flowOnePersonCheckout'), [nounSingular]), '#one-person-checkout'));
    28462912        } else {
    2847                 makingBooking.push(item(seatregFlowFormat(t('flowPerSeatCheckout'), [nounSingular]), '#one-person-checkout'));
     2913                makingBooking.push(item(seatregFormat(t('flowPerSeatCheckout'), [nounSingular]), '#one-person-checkout'));
    28482914        }
    28492915        if ($form.find('#require-name').is(':checked')) {
    … …  
    28552921        var emailLimit = parseInt($form.find('#bookings-email-limit').val(), 10);
    28562922        if (!isNaN(emailLimit) && emailLimit > 0) {
    2857                 makingBooking.push(item(seatregFlowFormat(t('flowEmailLimit'), [emailLimit, nounPlural]), '#bookings-email-limit'));
     2923                makingBooking.push(item(seatregFormat(t('flowEmailLimit'), [emailLimit, nounPlural]), '#bookings-email-limit'));
    28582924        }
    28592925        var $customFields = $form.find('.existing-custom-fields .custom-container');
    … …  
    28932959                var pendingExpiration = parseInt($form.find('#pending-expiration').val(), 10);
    28942960                if (!isNaN(pendingExpiration) && pendingExpiration > 0) {
    2895                         var expirationText = seatregFlowFormat(t('flowPendingExpiration'), [pendingExpiration]);
     2961                        var expirationText = seatregFormat(t('flowPendingExpiration'), [pendingExpiration]);
    28962962
    28972963                        // Payment statuses that don't block deletion of an expired pending booking.
    … …  
    29012967                        });
    29022968                        if (deletableStatusLabels.length > 0) {
    2903                                 expirationText += ' ' + seatregFlowFormat(t('flowPendingExpirationStatuses'), [deletableStatusLabels.join(', ')]);
     2969                                expirationText += ' ' + seatregFormat(t('flowPendingExpirationStatuses'), [deletableStatusLabels.join(', ')]);
    29042970                        }
    29052971
  • seatreg/trunk/js/utils.js

    r3486068 r3693621  
    2828}
    2929
     30// Lightweight printf-style replace supporting %s, %d and positional %1$d, %2$s tokens.
     31function seatregFormat(template, args) {
     32        if (!args || !args.length) {
     33                return template;
     34        }
     35
     36        return template
     37                .replace(/%(\d+)\$[ds]/g, function(match, position) {
     38                        return args[parseInt(position, 10) - 1];
     39                })
     40                .replace(/%[ds]/g, (function() {
     41                        var index = 0;
     42                        return function() {
     43                                return args[index++];
     44                        };
     45                })());
     46}
     47
     48/**
     49 * The word a registration uses for a room, in all four forms. The builder swaps registrations
     50 * without a reload so its nouns arrive with the layout, and so does the registration view, which
     51 * has no localized object; every other screen reloads and gets them from that.
     52 * @returns {Object} with singular, plural, singularUpper and pluralUpper
     53 */
     54function seatregRoomNouns() {
     55        if (window.seatreg && window.seatreg.roomNouns) {
     56                return window.seatreg.roomNouns;
     57        }
     58
     59        return window.WP_Seatreg && WP_Seatreg.room_nouns;
     60}
     61
     62/**
     63 * The word a registration uses for a seat, in the same four forms and reaching the screen the
     64 * same two ways.
     65 * @returns {Object} with singular, plural, singularUpper and pluralUpper
     66 */
     67function seatregSeatNouns() {
     68        if (window.seatreg && window.seatreg.seatNouns) {
     69                return window.seatreg.seatNouns;
     70        }
     71
     72        return window.WP_Seatreg && WP_Seatreg.seat_nouns;
     73}
     74
     75/**
     76 * Repaints the builder chrome, which is rendered once for no registration in particular.
     77 * A node names the noun it wants in data-seatreg-noun-kind and data-seatreg-noun and, when the
     78 * noun sits inside a sentence, that sentence in data-seatreg-noun-template. A sentence needing
     79 * more than one form lists them comma separated, in the order the sentence takes them.
     80 * data-seatreg-noun-attr writes to that attribute instead of the node's text.
     81 */
     82function seatregApplyNouns() {
     83        var nodes = document.querySelectorAll('[data-seatreg-noun]');
     84        var nouns = {
     85                room: seatregRoomNouns(),
     86                seat: seatregSeatNouns()
     87        };
     88
     89        for (var i = 0; i < nodes.length; i++) {
     90                var kind = nouns[nodes[i].getAttribute('data-seatreg-noun-kind')];
     91
     92                if (!kind) {
     93                        continue;
     94                }
     95
     96                var forms = nodes[i].getAttribute('data-seatreg-noun').split(',');
     97                var template = nodes[i].getAttribute('data-seatreg-noun-template');
     98                var attribute = nodes[i].getAttribute('data-seatreg-noun-attr');
     99                var nounArgs = [];
     100
     101                for (var j = 0; j < forms.length; j++) {
     102                        nounArgs.push(kind[forms[j]]);
     103                }
     104
     105                var text = template ? seatregFormat(template, nounArgs) : nounArgs[0];
     106
     107                if (attribute) {
     108                        nodes[i].setAttribute(attribute, text);
     109                } else {
     110                        nodes[i].textContent = text;
     111                }
     112        }
     113}
     114
    30115/**
    31116 * Creates a translator object for handling WP_Seatreg translations
  • seatreg/trunk/php/SeatregBooking.php

    r3624498 r3693621  
    4848        protected $_require_name = true; //require full name from registrants
    4949        protected $_couponsEnabled = false;
     50        protected $_roomNouns = null;
     51        protected $_seatNouns = null;
    5052       
    5153    protected function generateSeatString() {
    … …  
    5456
    5557        for($i = 0; $i < $dataLen; $i++) {
    56                 $seatsString .= esc_html__('Seat nr', 'seatreg') . ': <b>' . esc_html($this->_bookings[$i]->seat_nr) . '</b> ' . esc_html__('from room', 'seatreg') . ': <b>' . esc_html($this->_bookings[$i]->room_name) . '</b><br/>';
     58                /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat number, %3$s: the word the admin uses for a room */
     59                $seatsString .= sprintf(
     60                        wp_kses( __('%1$s nr: <b>%2$s</b> from %3$s', 'seatreg'), array( 'b' => array() ) ),
     61                        esc_html($this->_seatNouns->singularUpper),
     62                        esc_html($this->_bookings[$i]->seat_nr),
     63                        esc_html($this->_roomNouns->singular)
     64                ) . ': <b>' . esc_html($this->_bookings[$i]->room_name) . '</b><br/>';
    5765                }
    5866               
    … …  
    6977                        for($j = 0; $j < $bookedBookingsLength; $j++) {
    7078                                if($this->_bookings[$i]->seat_id == $bookedBookings[$j]->seat_id) {
    71                                         $statusReport = 'Seat <b>'. esc_html($this->_bookings[$i]->seat_nr) . '</b> in room <b>' . esc_html($this->_bookings[$i]->room_name) . '</b > is already confirmed';
     79                                        /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat number, %3$s: the word the admin uses for a room, %4$s: Room name */
     80                                        $statusReport = sprintf(
     81                                                wp_kses( __('%1$s <b>%2$s</b> in %3$s <b>%4$s</b> is already confirmed', 'seatreg'), array( 'b' => array() ) ),
     82                                                esc_html($this->_seatNouns->singularUpper),
     83                                                esc_html($this->_bookings[$i]->seat_nr),
     84                                                esc_html($this->_roomNouns->singular),
     85                                                esc_html($this->_bookings[$i]->room_name)
     86                                        );
    7287
    7388                                        if( $calendarDate ) {
    … …  
    87102                foreach( $this->_bookings as $booking ) {
    88103                        if( SeatregLayoutService::checkIfSeatLocked($this->_registrationLayoutFull, $booking->seat_id) ) {
    89                                 /* translators: %s: Seat number */
    90                                 $statusReport = sprintf(esc_html__('Seat %s is locked', 'seatreg'), $booking->seat_nr);
     104                                /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat number */
     105                                $statusReport = sprintf(esc_html__('%1$s %2$s is locked', 'seatreg'), esc_html($this->_seatNouns->singularUpper), $booking->seat_nr);
    91106
    92107                                break;
    … …  
    106121
    107122                                if( SeatregLayoutService::getSeatPassword($this->_registrationLayoutFull, $booking->seat_id) !== $enteredPassword ) {
    108                                         /* translators: %s: Seat number */
    109                                         $statusReport = sprintf(esc_html__('Seat %s password is not correct', 'seatreg'), $booking->seat_nr);
     123                                        /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat number */
     124                                        $statusReport = sprintf(esc_html__('%1$s %2$s password is not correct', 'seatreg'), esc_html($this->_seatNouns->singularUpper), $booking->seat_nr);
    110125
    111126                                        break;
    … …  
    233248
    234249                        if($searchStatus == 'room-searching') {
    235                                 $status = 'Room '. esc_html($this->_bookings[$i]->room_name) . ' was not found';
     250                                /* translators: %1$s: the word the admin uses for a room, capitalized, %2$s: Room name */
     251                                $status = sprintf(
     252                                        esc_html__('%1$s %2$s was not found', 'seatreg'),
     253                                        esc_html($this->_roomNouns->singularUpper),
     254                                        esc_html($this->_bookings[$i]->room_name)
     255                                );
    236256                                $allCorrect = false;
    237257
    … …  
    337357                $this->_require_name = $result->require_name === '1';
    338358                $this->_couponsEnabled = $result->enable_coupons === '1';
     359                $this->_roomNouns = SeatregTerminologyService::getRoomNouns($result);
     360                $this->_seatNouns = SeatregTerminologyService::getSeatNouns($result);
    339361               
    340362        if($result->gmail_required == '1') {
  • seatreg/trunk/php/SeatregDataValidation.php

    r3624498 r3693621  
    8080        if( strlen($registrationName) > SEATREG_REGISTRATION_NAME_MAX_LENGTH ) {
    8181                        $validationStatus->setInvalid('Registration name too long');
     82                }
     83
     84        return $validationStatus;
     85    }
     86
     87    public static function validateNoun($noun) {
     88        $validationStatus = new SeatregValidationStatus();
     89
     90        //Empty means the registration keeps the default wording
     91        if( $noun === '' ) {
     92            return $validationStatus;
     93        }
     94
     95        if( preg_match(SEATREG_NOUN_REGEX, $noun) !== 1 ) {
     96                        $validationStatus->setInvalid('Noun is too long or contains illegal characters');
    8297                }
    8398
  • seatreg/trunk/php/bookings/SeatregBookingPDF.php

    r3624498 r3693621  
    99    private $_bookingData;
    1010    private $_payment;
    11     private $_usingSeats;
    1211    private $_customFields;
    1312    private $_roomData;
    … …  
    178177
    179178    protected function buildDocument() {
     179        /* translators: %s: the word the admin uses for a seat, capitalized */
     180        $placeNumberText = esc_html( sprintf( __('%s number', 'seatreg'), SeatregTerminologyService::getSeatNouns($this->_bookingData)->singularUpper ) );
     181        /* translators: %s: the word the admin uses for a room, capitalized */
     182        $roomNameText = esc_html( sprintf( __('%s name', 'seatreg'), SeatregTerminologyService::getRoomNouns($this->_bookingData)->singularUpper ) );
    180183
    181184        foreach( $this->_bookings as $booking ) {
    182             $placeNumberText = $this->_bookingData->using_seats ? esc_html__('Seat number', 'seatreg') : esc_html__('Place number', 'seatreg');
    183185            $bookingDate = SeatregTimeService::getDateStringFromUnix($booking->booking_date);
    184186            $status = $this->getStatus($booking->status);
    … …  
    189191
    190192            $this->Cell(20, 6, $placeNumberText . ': ' . esc_html($booking->seat_nr), 0, 1, 'L');
    191             $this->Cell(20, 6, esc_html__('Room name', 'seatreg') . ': ' . esc_html($booking->room_name), 0, 1, 'L');
     193            $this->Cell(20, 6, $roomNameText . ': ' . esc_html($booking->room_name), 0, 1, 'L');
    192194
    193195            if( $seatLegend ) {
  • seatreg/trunk/php/bookings/SeatregBookingsFile.php

    r3624498 r3693621  
    1313    protected $_customFields = null;
    1414    protected $_currentTimestamp = null;
    15     protected $_usingSeats = true;
    1615    protected $_calendarDate = null;
    1716    protected $_separateFirstandLastName = false;
    1817    protected $_roomData = null;
     18    protected $_roomNouns = null;
     19    protected $_seatNouns = null;
    1920
    2021    public function __construct($showPending, $showConfirmed, $separateFirstandLastName, $registrationCode, $calendarDate) {
    … …  
    4344        $this->_registrations = $this->filtering( seatreg_get_data_for_booking_file($this->_registrationCode, $this->_showWhat, $this->_calendarDate) );
    4445        $this->_registrationName = esc_html($this->_registrationInfo->registration_name);
    45         $this->_usingSeats = $this->_registrationInfo->using_seats === '1';
     46        $this->_roomNouns = SeatregTerminologyService::getRoomNouns($this->_registrationInfo);
     47        $this->_seatNouns = SeatregTerminologyService::getSeatNouns($this->_registrationInfo);
    4648        $this->_roomData = SeatregLayoutService::getRoomDataFromLayout( $this->_registrationInfo->registration_layout );
    4749    }
  • seatreg/trunk/php/bookings/SeatregBookingsPDF.php

    r3624498 r3693621  
    6060        $registrationsLenght = count($this->_registrations);
    6161        $customFieldsLength = count($this->_customFields);
     62        /* translators: %s: the word the admin uses for a seat, capitalized */
     63        $placeNumberText = esc_html( sprintf( __('%s number', 'seatreg'), $this->_seatNouns->singularUpper ) );
    6264
    6365        foreach ($this->_registrations as $registration) {
    … …  
    6567            $status = $this->getStatus($registration->status);
    6668            $bookingDate = SeatregTimeService::getDateStringFromUnix($registration->booking_date);
    67             $placeNumberText = $this->_usingSeats ? esc_html__('Seat number', 'seatreg') : esc_html__('Place number', 'seatreg');
    6869            $seatPrice = SeatregLayoutService::getSeatPriceFromLayout($registration, $this->_roomData);
    6970            $usedCouponString = SeatregCouponService::getAppliedCouponString(json_decode($registration->applied_coupon) ?? null);
    … …  
    7172
    7273            $this->pdf->Cell(20, 6, $placeNumberText . ': ' . esc_html($registration->seat_nr), 0, 1, 'L');
    73             $this->pdf->Cell(20, 6, esc_html__('Room name', 'seatreg') . ': ' . esc_html($registration->room_name), 0, 1, 'L');
     74            /* translators: %s: the word the admin uses for a room, capitalized */
     75            $this->pdf->Cell(20, 6, esc_html( sprintf( __('%s name', 'seatreg'), $this->_roomNouns->singularUpper ) ) . ': ' . esc_html($registration->room_name), 0, 1, 'L');
    7476
    7577            if( $seatLegend ) {
  • seatreg/trunk/php/bookings/SeatregBookingsTxt.php

    r3624498 r3693621  
    2727        echo esc_html($this->_registrationName), esc_html($this->lineBreak());
    2828        echo esc_html__('Date', 'seatreg'), ': ', esc_html(date('Y-M-d H:i:s e', $this->_currentTimestamp)), esc_html($this->lineBreak()), esc_html($this->lineBreak());
    29         $placeNumberText = $this->_usingSeats ? esc_html__('Seat number', 'seatreg') : esc_html__('Place number', 'seatreg');
     29        /* translators: %s: the word the admin uses for a seat, capitalized */
     30        $placeNumberText = esc_html( sprintf( __('%s number', 'seatreg'), $this->_seatNouns->singularUpper ) );
    3031
    3132        foreach ($this->_registrations as $registration) {
    … …  
    3839
    3940            echo esc_html($placeNumberText), ': ', esc_html($registration->seat_nr), esc_html($this->lineBreak());
    40             echo esc_html__('Room', 'seatreg'), ': ', esc_html($registration->room_name), esc_html($this->lineBreak());
     41            echo esc_html($this->_roomNouns->singularUpper), ': ', esc_html($registration->room_name), esc_html($this->lineBreak());
    4142
    4243            if( $seatLegend ) {
  • seatreg/trunk/php/bookings/SeatregBookingsXlsx.php

    r3624498 r3693621  
    5858   
    5959    public function printXlsx() {
    60         $placeNumberText = $this->_usingSeats ? esc_html__('Seat number', 'seatreg') : esc_html__('Place number', 'seatreg');
     60        /* translators: %s: the word the admin uses for a seat, capitalized */
     61        $placeNumberText = esc_html( sprintf( __('%s number', 'seatreg'), $this->_seatNouns->singularUpper ) );
    6162        $hasSeatLegends = $this->hasSeatLegends();
    6263
    … …  
    7778            array(
    7879                $placeNumberText => 'string',
    79                 esc_html__('Room name', 'seatreg') => 'string',
     80                /* translators: %s: the word the admin uses for a room, capitalized */
     81                esc_html( sprintf( __('%s name', 'seatreg'), $this->_roomNouns->singularUpper ) ) => 'string',
    8082            ),
    8183            $labelHeader,
  • seatreg/trunk/php/constants.php

    r3680221 r3693621  
    1010
    1111// DB
    12 define('SEATREG_DB_VERSION', '1.63');
     12define('SEATREG_DB_VERSION', '1.65');
    1313
    1414// Validation
    … …  
    2323define("SEATREG_COUPON_UUID_REGEX", '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i');
    2424define("SEATREG_ROOM_DESCRIPTION_REGEX", '/^[\p{L}\p{N}\s\r\n.,-]+$/u');
     25define('SEATREG_NOUN_MAX_LENGTH', 50);
     26//No % or $ so a noun can never be mistaken for a sprintf token by the strings it gets substituted into
     27define('SEATREG_NOUN_REGEX', '/^[\p{L}\p{N} \'-]{1,50}$/u');
    2528
    2629// Payments
    … …  
    114117define('SEATREG_ACTION_BOOKING_REMOVED', 'seatreg_action_booking_removed');
    115118
     119// SeatReg filters
     120define('SEATREG_FILTER_ROOM_NOUNS', 'seatreg_room_nouns');
     121define('SEATREG_FILTER_SEAT_NOUNS', 'seatreg_seat_nouns');
     122
     123// Multilingual
     124//The group a translator sees in Polylang and the domain they see in WPML, so it is the plugin name
     125define('SEATREG_TRANSLATION_STRING_GROUP', 'SeatReg');
     126
    116127// API
    117128define('SEATREG_API_OK_MESSAGE', 'ok');
  • seatreg/trunk/php/enqueue_admin.php

    r3680221 r3693621  
    3535                wp_enqueue_style('vanilla_picker_style', plugins_url('js/vanilla-picker/dist/vanilla-picker.csp.css', dirname(__FILE__) ), array(), '2.12.1', 'all');
    3636                wp_enqueue_style('seatreg_builder_style', plugins_url('css/seatreg_builder.min.css', dirname(__FILE__) ), array(), '1.3.0', 'all');
    37                 wp_enqueue_style('seatreg_admin_styles', plugins_url('css/seatreg_admin.min.css', dirname(__FILE__) ), array(), '1.47.0', 'all');
     37                wp_enqueue_style('seatreg_admin_styles', plugins_url('css/seatreg_admin.min.css', dirname(__FILE__) ), array(), '1.50.0', 'all');
    3838                wp_enqueue_style('local-open-sans', SEATREG_PLUGIN_FOLDER_URL . 'fonts/open-sans/open-sans.css', array(), '1.0.0', 'all');
    3939                wp_enqueue_style('powertip_style', plugins_url('css/jquery.powertip.css', dirname(__FILE__) ), array(), '1.0.0', 'all');
    … …  
    5858                wp_enqueue_script('powertip', plugins_url('js/jquery.powertip.js', dirname(__FILE__) ), array('jquery'), '1.2.0', true);
    5959                wp_enqueue_script('date-format', plugins_url('js/date.format.js', dirname(__FILE__) ), array('jquery'), '1.0.0', true);
    60                 wp_enqueue_script('seatreg_admin_chart', plugins_url('js/Chart.min.js', dirname(__FILE__) ), array('jquery'), '1.0.0', true);
    61                 wp_enqueue_script('seatreg-utils', plugins_url('js/utils.js', dirname(__FILE__) ) , array(), '1.2.0', true);
    62                 wp_enqueue_script('seatreg_admin', plugins_url('js/seatreg_admin.js', dirname(__FILE__) ), array('jquery', 'powertip', 'seatreg_admin_chart', 'seatreg-utils'), '1.43.0', true);
     60                wp_enqueue_script('seatreg-utils', plugins_url('js/utils.js', dirname(__FILE__) ) , array(), '1.4.0', true);
     61
     62                //Only the Overview draws charts, so the library stays off every other screen
     63                if( $screen->id === 'seatreg_page_seatreg-overview' ) {
     64                        wp_enqueue_script('seatreg_admin_chart', plugins_url('js/chart.umd.min.js', dirname(__FILE__) ), array(), '4.4.7', true);
     65                }
     66
     67                wp_enqueue_script('seatreg_admin', plugins_url('js/seatreg_admin.js', dirname(__FILE__) ), array('jquery', 'powertip', 'seatreg-utils'), '1.46.0', true);
    6368                wp_enqueue_script('jstz', plugins_url('js/jstz-1.0.4.min.js', dirname(__FILE__) ), array(), '1.0.4', true);
    64                 wp_enqueue_script('seatreg_builder_script', plugins_url('js/build.js', dirname(__FILE__) ), array('jquery','jquery-ui-core','alertify','vanilla_picker','powertip', 'seatreg-utils', 'seatreg_admin'), '1.11.2', true);
     69                wp_enqueue_script('seatreg_builder_script', plugins_url('js/build.js', dirname(__FILE__) ), array('jquery','jquery-ui-core','alertify','vanilla_picker','powertip', 'seatreg-utils', 'seatreg_admin'), '1.13.0', true);
    6570
    6671                $seatreg_admin_strings_json = wp_json_encode(seatreg_generate_admin_strings());
    … …  
    6974                }
    7075
     76                //Every screen but the builder reloads when the registration changes, so its noun can be resolved here
     77                $seatreg_screen_tab = isset($_GET['tab']) ? sanitize_text_field( wp_unslash($_GET['tab']) ) : null;
     78
     79                if( !$seatreg_screen_tab ) {
     80                        //Without a tab the screens fall back to the first registration, as seatreg_generate_tabs() does
     81                        $seatreg_registrations = SeatregRegistrationRepository::getRegistrations();
     82                        $seatreg_screen_tab = count($seatreg_registrations) !== 0 ? $seatreg_registrations[0]->registration_code : null;
     83                }
     84
     85                $seatreg_screen_options = $seatreg_screen_tab ? SeatregOptionsRepository::getOptionsByRegistrationCode($seatreg_screen_tab) : null;
     86
    7187                wp_localize_script('seatreg_admin', 'WP_Seatreg', array(
    7288                        'nonce' => wp_create_nonce('seatreg-admin-nonce'),
     89                        'room_nouns' => SeatregTerminologyService::getRoomNouns($seatreg_screen_options),
     90                        'seat_nouns' => SeatregTerminologyService::getSeatNouns($seatreg_screen_options),
    7391                        'plugin_dir_url' => plugin_dir_url( dirname( __FILE__ ) ),
    7492                        'translations' => $seatreg_admin_strings_json,
  • seatreg/trunk/php/enqueue_public.php

    r3641857 r3693621  
    8383                wp_enqueue_script('jquery-powertip', SEATREG_PLUGIN_FOLDER_URL . 'js/jquery.powertip.js' , array(), '1.2.0', true);
    8484                wp_enqueue_script('pg-calendar', SEATREG_PLUGIN_FOLDER_URL . 'js/pg-calendar/dist/js/pignose.calendar.full.min.js' , array('jquery'), '1.4.31', false);
    85                 wp_enqueue_script('seatreg-utils', SEATREG_PLUGIN_FOLDER_URL . 'js/utils.js' , array(), '1.2.0', true);
    86                 wp_enqueue_script('seatreg-registration', SEATREG_PLUGIN_FOLDER_URL . 'registration/js/registration.js' , array('jquery', 'date-format', 'iscroll-zoom', 'jquery-powertip', 'seatreg-utils'), '1.37.0', true);
     85                wp_enqueue_script('seatreg-utils', SEATREG_PLUGIN_FOLDER_URL . 'js/utils.js' , array(), '1.4.0', true);
     86                wp_enqueue_script('seatreg-registration', SEATREG_PLUGIN_FOLDER_URL . 'registration/js/registration.js' , array('jquery', 'date-format', 'iscroll-zoom', 'jquery-powertip', 'seatreg-utils'), '1.39.0', true);
    8787                wp_enqueue_script('alertify', SEATREG_PLUGIN_FOLDER_URL . 'js/alertify.js', array('jquery'), '1.0.0', true);
    8888
    … …  
    127127                        $inlineScript .= 'var payPalCurrencyCode = "'. esc_js($data->paypal_currency_code) . '";';
    128128                        $inlineScript .= 'var receiptEnabled = "'. esc_js( $data->send_approved_booking_email) . '";';
    129                         $inlineScript .= 'var usingSeats = "'. esc_js( $data->using_seats ) . '";';
     129                        //Where seatregRoomNouns() and seatregSeatNouns() look first, so the accessors read the same on both sides
     130                        $inlineScript .= 'window.seatreg = window.seatreg || {};';
     131                        $inlineScript .= 'window.seatreg.roomNouns = jQuery.parseJSON(' . wp_json_encode( wp_json_encode( SeatregTerminologyService::getRoomNouns($data) ) ) . ');';
     132                        $inlineScript .= 'window.seatreg.seatNouns = jQuery.parseJSON(' . wp_json_encode( wp_json_encode( SeatregTerminologyService::getSeatNouns($data) ) ) . ');';
    130133                        $inlineScript .= 'var usingCalendar = "'. esc_js( $data->using_calendar ) . '";';
    131134                        $inlineScript .= 'var calendarDates = "'. esc_js( $data->calendar_dates ) . '";';
  • seatreg/trunk/php/repositories/SeatregOptionsRepository.php

    r3674169 r3693621  
    2323                ) );
    2424    }
     25    /**
     26     *
     27     * Return the code and nouns of every registration that renamed its rooms or its seats
     28     *
     29     */
     30    public static function getCustomNouns() {
     31        global $wpdb;
     32        global $seatreg_db_table_names;
     33
     34        return $wpdb->get_results(
     35            "SELECT b.registration_code, b.room_noun_singular, b.room_noun_plural, b.seat_noun_singular, b.seat_noun_plural
     36            FROM $seatreg_db_table_names->table_seatreg AS a
     37            INNER JOIN $seatreg_db_table_names->table_seatreg_options AS b ON a.registration_code = b.registration_code
     38            WHERE a.is_deleted = 0
     39            AND ( b.room_noun_singular IS NOT NULL OR b.room_noun_plural IS NOT NULL
     40                OR b.seat_noun_singular IS NOT NULL OR b.seat_noun_plural IS NOT NULL )"
     41        );
     42    }
     43
    2544     /**
    2645     *
  • seatreg/trunk/php/repositories/SeatregRegistrationRepository.php

    r3680221 r3693621  
    6161                b.registration_start_timestamp, b.registration_end_timestamp,
    6262                b.registration_start_time, b.registration_end_time,
    63                 b.using_calendar, b.calendar_dates
     63                b.using_calendar, b.calendar_dates,
     64                b.using_seats, b.room_noun_singular, b.room_noun_plural, b.seat_noun_singular, b.seat_noun_plural
    6465            FROM $seatreg_db_table_names->table_seatreg AS a
    6566            LEFT JOIN $seatreg_db_table_names->table_seatreg_options AS b
  • seatreg/trunk/php/seatreg_actions.php

    r3674169 r3693621  
    5757//.htaccess
    5858add_action( 'admin_init', 'seatreg_add_rewrite_rule' );
     59
     60add_action( 'admin_init', array( 'SeatregStringTranslationService', 'registerStrings' ) );
  • seatreg/trunk/php/seatreg_admin_panel.php

    r3680221 r3693621  
    132132                        ?>
    133133                        <div class="seatreg-tabs-content">
    134                                 <div id="existing-regs-wrap">
    135                                         <?php seatreg_generate_overview_section('overview'); ?>
    136                                 </div>
     134                                <?php seatreg_generate_overview_section(); ?>
    137135                        </div>
    138136                </div>
  • seatreg/trunk/php/seatreg_functions.php

    r3680221 r3693621  
    203203*/
    204204
    205 function seatreg_generate_overview_section($targetRoom) {
    206         global $wpdb;
    207         global $seatreg_db_table_names;
    208 
     205function seatreg_generate_overview_section() {
    209206        $active_tab = null;
    210207
    … …  
    216213                        wp_die( esc_html($validation->errorMessage) );
    217214                }
    218         }
    219         $registration = seatreg_get_options( $active_tab )[0];
    220         $filterBookingsByDate = SeatregCalendarService::getBookingFilteringDate($registration->using_calendar);
    221 
    222         seatreg_generate_overview_section_html($targetRoom, $active_tab, $filterBookingsByDate);
    223 }
    224 
    225 //generate overview section html.
    226 function seatreg_generate_overview_section_html($targetRoom, $active_tab, $filterBookingsByDate) {
    227         global $wpdb;
    228         global $seatreg_db_table_names;
    229 
    230         $registration = seatreg_get_options( $active_tab );
    231 
    232         if( count($registration) == 0 ) {
     215        }
     216
     217        $registrations = seatreg_get_options( $active_tab );
     218
     219        if( count($registrations) === 0 ) {
    233220                seatreg_no_registration_created_info();
    234                  
    235                 return;
    236          }
    237 
    238         $registration = $registration[0];
    239 
    240         $bookings = SeatregBookingRepository::getConfirmedAndApprovedBookingsByRegistrationCode( $registration->registration_code );
    241         $pendingBookingsRoomInfo = [];
    242         $confirmedBookingsRoomInfo = [];
    243 
    244         if($registration->using_calendar === '1') {
    245                 $pendingBookingsRoomInfo = $wpdb->get_results("SELECT room_uuid, COUNT(id) AS total FROM $seatreg_db_table_names->table_seatreg_bookings WHERE registration_code = '$registration->registration_code' AND calendar_date = '$filterBookingsByDate' AND status = 1 AND is_deleted = 0 GROUP BY room_uuid");
    246                 $confirmedBookingsRoomInfo = $wpdb->get_results("SELECT room_uuid, COUNT(id) AS total FROM $seatreg_db_table_names->table_seatreg_bookings WHERE registration_code = '$registration->registration_code' AND calendar_date = '$filterBookingsByDate' AND status = 2 AND is_deleted = 0 GROUP BY room_uuid");
    247         }else {
    248                 $pendingBookingsRoomInfo = $wpdb->get_results("SELECT room_uuid, COUNT(id) AS total FROM $seatreg_db_table_names->table_seatreg_bookings WHERE registration_code = '$registration->registration_code' AND calendar_date IS NULL AND status = 1 AND is_deleted = 0 GROUP BY room_uuid");
    249                 $confirmedBookingsRoomInfo = $wpdb->get_results("SELECT room_uuid, COUNT(id) AS total FROM $seatreg_db_table_names->table_seatreg_bookings WHERE registration_code = '$registration->registration_code' AND calendar_date IS NULL AND status = 2 AND is_deleted = 0 GROUP BY room_uuid");
    250         }
    251        
    252         $regStats = seatreg_get_room_seat_info($registration->registration_layout, $pendingBookingsRoomInfo, $confirmedBookingsRoomInfo);
    253         $project_name = $registration->registration_name;
    254         $start_date = $registration->registration_start_timestamp;
    255         $end_date = $registration->registration_end_timestamp;
    256         $regUrl =  get_site_url();
    257         $roomLoactionInStats = -1;
    258         $rName = str_replace(" ", "-", $registration->registration_name);
    259 
    260         ?>
    261 
    262                         <?php echo '<div class="reg-overview" id="existing-regs">';?>
    263                                 <input type="hidden" id="seatreg-reg-code" value="<?php echo esc_attr($registration->registration_code); ?>"/>
    264 
    265                                   <?php if($registration->using_calendar === '1') : ?>
    266                                         <div class="overview-calendar-wrap">
    267                                         <label for="overview-calendar-date"><?php esc_html_e('Date', 'seatreg'); ?> <i class="fa fa-calendar" aria-hidden="true"></i></label>
    268                                                 <input type="text" id="overview-calendar-date" class="" value="<?php echo esc_attr($filterBookingsByDate); ?>" autocomplete="off" />
    269 
    270                                                 <input type='hidden' value='<?php echo esc_html($filterBookingsByDate); ?>' id='overview-calendar-date-value' />
    271                                         </div>
    272                                 <?php endif; ?>
    273 
    274                                 <?php echo '<div class="reg-overview-top">';?>
    275                                         <?php
    276                                                 if($targetRoom == 'overview') {
    277                                                         echo '<div class="reg-overview-top-header">';
    278                                                                 echo esc_html($project_name);
    279                                                         echo '</div>';
    280                                                 }else {
    281                                                         echo '<div class="reg-overview-top-header">';
    282                                                                 echo esc_html($targetRoom);
    283                                                         echo '</div>';
    284                                                 }
    285                                         ?>
    286 
    287                                         <?php
    288                                                 if($targetRoom == 'overview') {
    289                                                         echo "<div class='reg-overview-top-bron-notify'>";
    290                                                                 // translators: %s: Number of pending seats
    291                                                                 $pendingSeats = sprintf(esc_html__('%s pending seats', 'seatreg'), $regStats['bronSeats']);
    292                                                                 // translators: %s: Number of pending places
    293                                                                 $pendingPlaces = sprintf(esc_html__('%s pending places', 'seatreg'), $regStats['bronSeats']);
    294                                                                 echo esc_html($registration->using_seats === '1' ? $pendingSeats : $pendingPlaces) . '!';
    295                                                         echo '</div>';
    296                                                 }else {
    297                                                         for($i = 0; $i < $regStats['roomCount']; $i++) {
    298                                                                 if($regStats['roomsInfo'][$i]['roomName'] == $targetRoom) {
    299                                                                         echo '<div class="reg-overview-top-bron-notify">';
    300                                                                                 if( $registration->using_seats === '1' ) {
    301                                                                                         echo esc_html($regStats['roomsInfo'][$i]['roomBronSeats']),' ', esc_html__('pending seats', 'seatreg'), '!';
    302                                                                                 }else {
    303                                                                                         echo esc_html($regStats['roomsInfo'][$i]['roomBronSeats']),' ', esc_html__('pending places', 'seatreg'), '!';
    304                                                                                 }       
    305                                                                         echo '</div>';
    306                                                                        
    307                                                                         $roomLoactionInStats = $i;
    308 
    309                                                                         break;
    310                                                                 }
    311                                                         }
    312                                                 }
    313                                         ?>
    314 
    315                                         <?php
    316                                                 $start = esc_html__('Start date not set', 'seatreg');
    317                                                 $end = esc_html__('End date not set', 'seatreg');
    318 
    319                                                 if(!empty($start_date)) {
    320                                                         $start = $start_date;
    321                                                 }
    322 
    323                                                 if(!empty($end_date)) {
    324                                                         $end = $end_date;
    325                                                 }
    326                                                
    327                                                 echo "<div class='reg-overview-top-date'><span class='time-block'><i class='fa fa-clock-o' style='color:rgb(4, 145, 4); margin-right:3px'></i><span class='time-stamp'>" . esc_html($start) . "</span></span>  <span class='time-block'><i class='fa fa-clock-o' style='color:rgb(250, 38, 38); margin-right:3px'></i><span class='time-stamp'>" . esc_html($end) . "</span></span></div>";
    328                                         ?>
    329                                        
    330                                 <?php echo '</div>';?>
    331 
    332                                 <?php echo '<div class="reg-overview-middle-wrap">'; ?>                 
    333                                 <?php echo '<div class="reg-overview-aside">';?>
    334 
    335                                         <ul class="room-list">
    336                                                 <li class="room-list-item first-item" <?php if($targetRoom == 'overview') { echo 'data-active="true"';} ?> data-stats-target="overview"><?php esc_html_e('Overall', 'seatreg'); ?> </li>
    337 
    338                                                 <?php
    339                                                         for($i = 0; $i < $regStats['roomCount']; $i++) {
    340                                                                 if($regStats['roomsInfo'][$i]['roomName'] != $targetRoom) {
    341                                                                         echo '<li class="room-list-item" data-stats-target="', esc_attr($regStats['roomsInfo'][$i]['roomName']),'">', esc_html($regStats['roomsInfo'][$i]['roomName']),'</li>';
    342                                                                 }else {
    343                                                                         echo '<li class="room-list-item" data-active="true" data-stats-target="', esc_attr($regStats['roomsInfo'][$i]['roomName']),'">', esc_html($regStats['roomsInfo'][$i]['roomName']),'</li>';
    344                                                                 }
    345                                                         }       
    346                                                 ?>
    347                                                
    348                                         </ul>
    349 
    350                                 <?php echo '</div>';?>
    351 
    352                                 <?php echo '<div class="reg-overview-middle">';?>
    353                                         <div class="overview-middle-box">
    354                                                 <div class="overview-middle-box-h">
    355                                                         <?php $registration->using_seats === '1' ? esc_html_e('Seats', 'seatreg') : esc_html_e('Places', 'seatreg'); ?>
    356                                                 </div>
    357                                                 <div class="overview-middle-box-stat">
    358                                                         <?php
    359                                                                 if($targetRoom == 'overview') {
    360                                                                         echo esc_html($regStats['seatsTotal']);
    361                                                                 }else if($roomLoactionInStats >= 0) {
    362                                                                         echo esc_html($regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal']);
    363                                                                 }
    364                                                         ?>
    365                                                 </div> 
    366                                         </div>
    367 
    368                                         <div class="overview-middle-box">
    369                                                 <div class="overview-middle-box-h">
    370                                                         <?php esc_html_e('Open', 'seatreg'); ?>
    371                                                 </div>
    372                                                 <div class="overview-middle-box-stat">
    373                                                         <?php
    374                                                                 if($targetRoom == 'overview') {
    375                                                                         echo esc_html($regStats['openSeats']);
    376 
    377                                                                 }else if($roomLoactionInStats >= 0) {
    378                                                                         echo esc_html($regStats['roomsInfo'][$roomLoactionInStats]['roomOpenSeats']);
    379                                                                 }
    380                                                         ?>
    381                                                 </div> 
    382                                         </div>
    383 
    384                                         <div class="overview-middle-box">
    385                                                 <div class="overview-middle-box-h">
    386                                                         <?php esc_html_e('Confirmed', 'seatreg'); ?>
    387                                                 </div>
    388                                                 <div class="overview-middle-box-stat">
    389                                                         <?php
    390                                                                 if($targetRoom == 'overview') {
    391                                                                         echo esc_html($regStats['takenSeats']);
    392                                                                 }else if($roomLoactionInStats >= 0) {
    393                                                                         echo esc_html($regStats['roomsInfo'][$roomLoactionInStats]['roomTakenSeats']);
    394                                                                 }
    395                                                         ?>
    396                                                 </div> 
    397                                         </div>
    398 
    399                                         <div class="overview-middle-box">
    400                                                 <div class="overview-middle-box-h">
    401                                                         <?php esc_html_e('Pending', 'seatreg'); ?>
    402                                                 </div>
    403                                                 <div class="overview-middle-box-stat">
    404                                                         <?php
    405                                                                 if($targetRoom == 'overview') {
    406                                                                         echo esc_html($regStats['bronSeats']);
    407                                                                 }else if($roomLoactionInStats >= 0) {
    408                                                                         echo esc_html($regStats['roomsInfo'][$roomLoactionInStats]['roomBronSeats']);
    409                                                                 }
    410                                                         ?>
    411                                                 </div> 
    412                                         </div> 
    413 
    414                                 <?php echo '</div>';?>
    415 
    416                                 <?php echo '<div class="reg-overview-donuts">';?>
    417 
    418                                         <canvas class="stats-doughnut" height="100" width="100"></canvas>
    419 
    420                                         <div class="stats-doughnut-legend">
    421                                                 <?php if($regStats['seatsTotal']): ?>
    422 
    423                                                         <div class="legend-block"><span class="doughnut-legend" style="background-color:#61B329"></span><span style="padding-right: 12px"><?php esc_html_e('Open', 'seatreg'); ?> </span>
    424                                                                 <span class="legend-block-percent" style="color:#61B329">
    425                                                                         <?php
    426                                                                                 if($targetRoom == 'overview') {
    427                                                                                         echo esc_html( round(($regStats['openSeats'] / $regStats['seatsTotal']  ) * 100) ), '%';
    428                                                                                 }else if($roomLoactionInStats >= 0) {
    429 
    430                                                                                         if($regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal'] > 0) {
    431                                                                                                 echo esc_html( round(($regStats['roomsInfo'][$roomLoactionInStats]['roomOpenSeats'] / $regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal']  ) * 100, 2)), '%';
    432                                                                                         }else {
    433                                                                                                 echo '0%';
    434                                                                                         }
    435                                                                                 }
    436                                                                         ?>
    437                                                                 </span>
    438                                                         </div>
    439                                                         <div class="legend-block"><span class="doughnut-legend" style="background-color:red"></span><span style="padding-right: 12px"><?php esc_html_e('Confirmed', 'seatreg'); ?> </span>
    440                                                                 <span class="legend-block-percent" style="color:red">
    441                                                                         <?php
    442                                                                                 if($targetRoom == 'overview') {
    443                                                                                         echo esc_html(round(($regStats['takenSeats'] / $regStats['seatsTotal']  ) * 100)), '%';
    444                                                                                 }else if($roomLoactionInStats >= 0) {
    445 
    446                                                                                         if($regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal'] > 0) {
    447                                                                                                 echo esc_html(round(($regStats['roomsInfo'][$roomLoactionInStats]['roomTakenSeats'] / $regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal']  ) * 100, 2)), '%';
    448                                                                                         }else {
    449                                                                                                 echo '0%';
    450                                                                                         }
    451                                                                                 }
    452                                                                         ?>
    453                                                                 </span>
    454                                                         </div>
    455                                                         <div class="legend-block"><span class="doughnut-legend" style="background-color:yellow"></span><span style="padding-right: 12px"><?php esc_html_e('Pending', 'seatreg'); ?> </span>
    456                                                                 <span class="legend-block-percent" style="color:#26a6d1">
    457                                                                         <?php
    458                                                                                 if($targetRoom == 'overview') {
    459                                                                                         echo esc_html(round(($regStats['bronSeats'] / $regStats['seatsTotal']  ) * 100)), '%';
    460                                                                                 }else if($roomLoactionInStats >= 0) {
    461 
    462                                                                                         if($regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal'] > 0) {
    463                                                                                                 echo esc_html(round(($regStats['roomsInfo'][$roomLoactionInStats]['roomBronSeats'] / $regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal'] ) * 100, 2)), '%';
    464                                                                                         }else {
    465                                                                                                 echo '0%';
    466                                                                                         }                                                                                       
    467                                                                                 }               
    468                                                                         ?>
    469                                                                 </span>
    470                                                         </div>
    471                                                 <?php endif; ?>
    472                                         </div>
    473                                         <?php if($targetRoom == 'overview'): ?>
    474                                                 <input type="hidden" class="seats-total-don" value="<?php echo esc_attr($regStats['seatsTotal']); ?>"/>
    475                                                 <input type="hidden" class="seats-bron-don" value="<?php echo esc_attr($regStats['bronSeats']); ?>"/>
    476                                                 <input type="hidden" class="seats-taken-don" value="<?php echo esc_attr($regStats['takenSeats']); ?>"/>
    477                                                 <input type="hidden" class="seats-open-don" value="<?php echo esc_attr($regStats['openSeats']); ?>"/>
    478                                         <?php else: ?>
    479                                                 <input type="hidden" class="seats-total-don" value="<?php echo esc_attr($regStats['roomsInfo'][$roomLoactionInStats]['roomSeatsTotal']); ?>"/>
    480                                                 <input type="hidden" class="seats-bron-don" value="<?php echo esc_attr($regStats['roomsInfo'][$roomLoactionInStats]['roomBronSeats']); ?>"/>
    481                                                 <input type="hidden" class="seats-taken-don" value="<?php echo esc_attr($regStats['roomsInfo'][$roomLoactionInStats]['roomTakenSeats']); ?>"/>
    482                                                 <input type="hidden" class="seats-open-don" value="<?php echo esc_attr($regStats['roomsInfo'][$roomLoactionInStats]['roomOpenSeats']); ?>"/>
    483                                         <?php endif; ?>
    484 
    485                                 <?php echo '</div>';?>
    486                                 <?php echo '</div>'; ?>
    487                         <?php echo '</div>';?>
    488           <?php         
     221
     222                return;
     223        }
     224
     225        $seatregRegistration = $registrations[0];
     226        $seatregRequestedDate = assignIfNotEmpty( $_GET['calendar-date'], null );
     227        $seatregCalendarDate = SeatregCalendarService::getBookingFilteringDateForRegistrationView(
     228                $seatregRegistration->using_calendar,
     229                $seatregRequestedDate === null ? null : sanitize_text_field( $seatregRequestedDate )
     230        );
     231        $seatregStats = SeatregLayoutService::getBookingsInfoForLayout(
     232                $seatregRegistration->registration_layout,
     233                $seatregRegistration->registration_code,
     234                $seatregCalendarDate
     235        );
     236
     237        require( SEATREG_PLUGIN_FOLDER_DIR . 'php/views/sections/overview.php' );
    489238}
    490239
    … …  
    631380                                        </label>
    632381                                </div>
     382                        </div>
     383
     384                        <div class="form-group">
     385                                <p class="form-group-title"><?php esc_html_e('Rename seats', 'seatreg'); ?></p>
     386                                <p class="help-block">
     387                                        <?php esc_html_e('Enter the word to use instead of the one the setting above chooses, for example booth or bed. Both forms are needed. Leave them empty to keep the word above', 'seatreg'); ?>.
     388                                </p>
     389                                <label class="form-group-subfield-label" for="seat-noun-singular"><?php esc_html_e('Singular', 'seatreg'); ?></label>
     390                                <input type="text" class="form-control" id="seat-noun-singular" name="seat-noun-singular" autocomplete="off" maxlength="<?php echo esc_attr(SEATREG_NOUN_MAX_LENGTH); ?>" placeholder="<?php echo esc_attr($options[0]->using_seats == '1' ? __('seat', 'seatreg') : __('place', 'seatreg')); ?>" value="<?php echo esc_attr($options[0]->seat_noun_singular); ?>">
     391
     392                                <label class="form-group-subfield-label" for="seat-noun-plural"><?php esc_html_e('Plural', 'seatreg'); ?></label>
     393                                <input type="text" class="form-control" id="seat-noun-plural" name="seat-noun-plural" autocomplete="off" maxlength="<?php echo esc_attr(SEATREG_NOUN_MAX_LENGTH); ?>" placeholder="<?php echo esc_attr($options[0]->using_seats == '1' ? __('seats', 'seatreg') : __('places', 'seatreg')); ?>" value="<?php echo esc_attr($options[0]->seat_noun_plural); ?>">
     394
     395                                <?php if( SeatregStringTranslationService::isAvailable() ) : ?>
     396                                        <p class="help-block">
     397                                                <?php esc_html_e('Both words can be translated in your translation plugin, in the SeatReg string group', 'seatreg'); ?>.
     398                                        </p>
     399                                <?php endif; ?>
     400                        </div>
     401
     402                        <div class="form-group">
     403                                <p class="form-group-title"><?php esc_html_e('Rename rooms', 'seatreg'); ?></p>
     404                                <p class="help-block">
     405                                        <?php esc_html_e('Your layout is split into rooms. If your registration is not about rooms, enter the word to use instead, for example stall or hall. Both forms are needed. Leave them empty to keep "room"', 'seatreg'); ?>.
     406                                </p>
     407                                <label class="form-group-subfield-label" for="room-noun-singular"><?php esc_html_e('Singular', 'seatreg'); ?></label>
     408                                <input type="text" class="form-control" id="room-noun-singular" name="room-noun-singular" autocomplete="off" maxlength="<?php echo esc_attr(SEATREG_NOUN_MAX_LENGTH); ?>" placeholder="<?php esc_attr_e('room', 'seatreg'); ?>" value="<?php echo esc_attr($options[0]->room_noun_singular); ?>">
     409
     410                                <label class="form-group-subfield-label" for="room-noun-plural"><?php esc_html_e('Plural', 'seatreg'); ?></label>
     411                                <input type="text" class="form-control" id="room-noun-plural" name="room-noun-plural" autocomplete="off" maxlength="<?php echo esc_attr(SEATREG_NOUN_MAX_LENGTH); ?>" placeholder="<?php esc_attr_e('rooms', 'seatreg'); ?>" value="<?php echo esc_attr($options[0]->room_noun_plural); ?>">
     412
     413                                <?php if( SeatregStringTranslationService::isAvailable() ) : ?>
     414                                        <p class="help-block">
     415                                                <?php esc_html_e('Both words can be translated in your translation plugin, in the SeatReg string group', 'seatreg'); ?>.
     416                                        </p>
     417                                <?php endif; ?>
    633418                        </div>
    634419
    … …  
    19661751        $row_count3 = count($bookings3);
    19671752        $project_name = str_replace(' ', '_', $project_name_original);
    1968         $usingSeats = $seatregData->using_seats === '1';
     1753        $roomNouns = SeatregTerminologyService::getRoomNouns($seatregData);
     1754        $seatNouns = SeatregTerminologyService::getSeatNouns($seatregData);
    19691755        $requireName = $seatregData->require_name;
    19701756        $currencyCode = $seatregData->paypal_currency_code;
    … …  
    20271813                                        <div class="registration-manager-labels">
    20281814                                                <div class="seat-nr-box manager-box manager-box-link" data-order="nr">
    2029                                                         <?php $usingSeats ? esc_html_e('Seat', 'seatreg') : esc_html_e('Place', 'seatreg'); ?>
     1815                                                        <?php echo esc_html($seatNouns->singularUpper); ?>
    20301816                                                </div>
    2031                                                 <div class="seat-room-box manager-box manager-box-link" data-order="room"><?php esc_html_e('Room', 'seatreg'); ?></div>
     1817                                                <div class="seat-room-box manager-box manager-box-link" data-order="room"><?php echo esc_html($roomNouns->singularUpper); ?></div>
    20321818                                                <div class="seat-name-box manager-box manager-box-link" data-order="name"><?php esc_html_e('Name', 'seatreg'); ?></div>
    20331819                                                <div class="seat-name-box manager-box manager-box-link" data-order="date"><?php esc_html_e('Date', 'seatreg'); ?></div>
    … …  
    20411827                                        if($row_count == 0) {
    20421828                                                echo '<div class="notify-text">';
    2043                                                         $usingSeats ? esc_html_e('No pending bookings', 'seatreg') : esc_html_e('No pending places', 'seatreg');
     1829                                                        esc_html_e('No pending bookings', 'seatreg');
    20441830                                                echo '</div>';
    20451831                                        }                       
    … …  
    22662052        <?php
    22672053       
    2268         seatreg_booking_edit_modal($usingSeats, $calendarDate, $requireName);
    2269         seatreg_add_booking_modal($usingSeats, $calendarDate, $requireName, $roomsData);
     2054        seatreg_booking_edit_modal($calendarDate, $requireName, $roomNouns, $seatNouns);
     2055        seatreg_add_booking_modal($calendarDate, $requireName, $roomsData, $roomNouns, $seatNouns);
    22702056        seatreg_booking_activity_modal();
    22712057        seatreg_bookings_file_modal($custom_fields, $code, $calendarDate);
    2272         seatreg_seat_id_modal($roomsData, $bookings1, $bookings2);
     2058        seatreg_seat_id_modal($roomsData, $bookings1, $bookings2, $roomNouns, $seatNouns);
    22732059        seatreg_import_bookings_modal($code, $seatregData);
    22742060        seatreg_import_bookings_finalization_modal($code);
    … …  
    24342220}
    24352221
    2436 function seatreg_add_booking_modal($usingSeats, $calendarDate, $requireName, $roomsData) {
     2222//The layout builder is rendered once, before any registration is chosen, so it shows the default
     2223//wording and seatregApplyNouns() repaints it from the layout the admin opens.
     2224//$form names one form, or the comma separated forms a sentence needs in the order it needs them
     2225function seatreg_noun_text($kind, $form, $template = '') {
     2226        $nouns = $kind === 'seat' ? SeatregTerminologyService::getSeatNouns() : SeatregTerminologyService::getRoomNouns();
     2227        $forms = explode(',', $form);
     2228
     2229        if( $template === '' ) {
     2230                return $nouns->{$forms[0]};
     2231        }
     2232
     2233        return vsprintf($template, array_map(function($singleForm) use ($nouns) {
     2234                return $nouns->$singleForm;
     2235        }, $forms));
     2236}
     2237
     2238//What seatregApplyNouns() looks for. Every piece is escaped, so the caller echoes it as it is.
     2239function seatreg_noun_markers($kind, $form, $template = '', $attribute = '') {
     2240        return sprintf(
     2241                ' data-seatreg-noun-kind="%s" data-seatreg-noun="%s"%s%s',
     2242                esc_attr($kind),
     2243                esc_attr($form),
     2244                $template === '' ? '' : ' data-seatreg-noun-template="' . esc_attr($template) . '"',
     2245                $attribute === '' ? '' : ' data-seatreg-noun-attr="' . esc_attr($attribute) . '"'
     2246        );
     2247}
     2248
     2249function seatreg_noun_span($kind, $form, $template = '') {
     2250        printf(
     2251                '<span%s>%s</span>',
     2252                seatreg_noun_markers($kind, $form, $template),
     2253                esc_html( seatreg_noun_text($kind, $form, $template) )
     2254        );
     2255}
     2256
     2257function seatreg_add_booking_modal($calendarDate, $requireName, $roomsData, $roomNouns, $seatNouns) {
    24372258        if(!$roomsData) {
    24382259                return;
    … …  
    24452266}
    24462267
    2447 function seatreg_booking_edit_modal($usingSeats, $calendarDate, $requireName) {
     2268function seatreg_booking_edit_modal($calendarDate, $requireName, $roomNouns, $seatNouns) {
    24482269        require( SEATREG_PLUGIN_FOLDER_DIR . 'php/views/modals/booking-edit-modal.php' );
    24492270}
    … …  
    24612282}
    24622283
    2463 function seatreg_shortcode_modal($registrationCode, $rooms) {
     2284function seatreg_shortcode_modal($registrationCode, $rooms, $roomNouns) {
    24642285        require( SEATREG_PLUGIN_FOLDER_DIR . 'php/views/modals/shortcode-modal.php' );
    24652286}
    … …  
    24762297}
    24772298
    2478 function seatreg_seat_id_modal($roomsData, $pendingBookings, $approvedBookings) {
     2299function seatreg_seat_id_modal($roomsData, $pendingBookings, $approvedBookings, $roomNouns, $seatNouns) {
    24792300        $combinedBookings = array_merge($pendingBookings, $approvedBookings);
    24802301        $bookingIds = array_map(function($booking) {
    … …  
    26042425}
    26052426
    2606 //return room info. How many bron and taken seats are in a rooms
    2607 function seatreg_get_room_seat_info($struct, $bronRegistrations, $takenRegistrations) {
    2608         $bronLength = count($bronRegistrations);
    2609         $takenLength = count($takenRegistrations);
    2610         $regStructure = ($struct !== null) ? json_decode($struct)->roomData : null;
    2611         $roomCount = count(is_array($regStructure) ? $regStructure : []);
    2612         $howManyRegSeats = 0;
    2613         $howManyOpenSeats = 0;
    2614         $howManyBronSeats= 0;
    2615         $howManyTakenSeats = 0;
    2616         $howManyCustomBoxes = 0;
    2617         $statsArray = array();
    2618         $roomsInfo = array();
    2619 
    2620         for($i = 0; $i < $roomCount; $i++) {
    2621                 $roomBoxes = $regStructure[$i]->boxes;
    2622 
    2623                 //find how many bron seats in this room
    2624                 $roomBoxCount = count($roomBoxes);
    2625                 $roomRegSeats = 0;  //how many reg seats
    2626                 $roomOpenSeats = 0; //how many open reg seats
    2627                 $roomTakenSeats = 0; //how many taken seats
    2628                 $roomBronSeats = 0;     //bron seats
    2629                 $roomCustomBoxes = 0;
    2630 
    2631                 for($k = 0; $k < $bronLength; $k++) { 
    2632                         if( $regStructure[$i]->room->uuid == $bronRegistrations[$k]->room_uuid ) { //find how many bron seats in this room
    2633                                 $roomBronSeats = $bronRegistrations[$k]->total;
    2634                                 $howManyBronSeats += $bronRegistrations[$k]->total;
    2635 
    2636                                 break;
    2637                         }
    2638                 }
    2639 
    2640                 for($k = 0; $k < $takenLength; $k++) {
    2641                         if($regStructure[$i]->room->uuid == $takenRegistrations[$k]->room_uuid) { //find how many taken seats in this room
    2642                                 $roomTakenSeats = $takenRegistrations[$k]->total;
    2643                                 $howManyTakenSeats += $takenRegistrations[$k]->total;
    2644 
    2645                                 break;
    2646                         }
    2647                 }
    2648                
    2649                 for($j = 0; $j < $roomBoxCount; $j++) {
    2650                         if($roomBoxes[$j]->canRegister == 'true') {
    2651                                 if($roomBoxes[$j]->status == 'noStatus') {
    2652                                         $howManyOpenSeats++;
    2653                                         $roomOpenSeats++;
    2654                                 }
    2655                                
    2656                                 $howManyRegSeats++;
    2657                                 $roomRegSeats++;
    2658                         }else {
    2659                                 $howManyCustomBoxes++;
    2660                                 $roomCustomBoxes++;
    2661                         }
    2662                 }
    2663 
    2664                 $roomsInfo[] = array(
    2665                         'roomName' => $regStructure[$i]->room->name,
    2666                         'roomSeatsTotal' => $roomRegSeats,
    2667                         'roomOpenSeats' => $roomRegSeats - $roomTakenSeats - $roomBronSeats,
    2668                         'roomTakenSeats' => $roomTakenSeats,
    2669                         'roomBronSeats' => $roomBronSeats,
    2670                         'roomCustomBoxes' => $roomCustomBoxes
    2671                 );
    2672         }
    2673 
    2674         $statsArray['seatsTotal'] = $howManyRegSeats;
    2675         $statsArray['openSeats'] = $howManyOpenSeats - $howManyBronSeats - $howManyTakenSeats;
    2676         $statsArray['bronSeats'] = $howManyBronSeats;
    2677         $statsArray['takenSeats'] = $howManyTakenSeats;
    2678         $statsArray['roomCount'] = $roomCount;
    2679         $statsArray['roomsInfo'] = $roomsInfo;
    2680 
    2681         return $statsArray;
    2682 }
    2683 
    26842427function seatreg_validate_del_conf_booking($code, $bookingActions, $calendarDate) {
    26852428        $registration = seatreg_get_registration_data($code)[0];
    26862429        $structure = SeatregLayoutService::getRoomDataFromLayout($registration->registration_layout);
     2430        $roomNouns = SeatregTerminologyService::getRoomNouns($registration);
     2431        $seatNouns = SeatregTerminologyService::getSeatNouns($registration);
    26872432        $bookingActionLength = count($bookingActions);
    26882433        $seat_id;
    … …  
    26932438        //step 1. check if room exists and contains seat with nr
    26942439        foreach ($bookingActions as $key => $value) {
    2695                 $step1Desision = seatreg_check_room_and_seat($structure, $value->room_name, $value->seat_nr);
     2440                $step1Desision = seatreg_check_room_and_seat($structure, $value->room_name, $value->seat_nr, $roomNouns, $seatNouns);
    26962441
    26972442                if( $step1Desision['status'] != 'ok') {
    … …  
    27212466                        if($booking->seat_nr == $bookingAction->seat_nr && $booking->room_name == $bookingAction->room_name && $booking->status === "2" && $bookingAction->action != 'del' && $bookingAction->action != 'unapprove') {
    27222467                                $notBooked = false;
    2723                                 $resp['text'] = esc_html__('Seat ', 'seatreg') . esc_html($bookingAction->seat_nr) . esc_html__(' from room ', 'seatreg') . esc_html($bookingAction->room_name) . esc_html__(' is already booked', 'seatreg');
     2468                                /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat number, %3$s: the word the admin uses for a room, %4$s: Room name */
     2469                                $resp['text'] = sprintf( esc_html__('%1$s %2$s from %3$s %4$s is already booked', 'seatreg'), esc_html($seatNouns->singularUpper), esc_html($bookingAction->seat_nr), esc_html($roomNouns->singular), esc_html($bookingAction->room_name) );
    27242470
    27252471                                break 2;
    … …  
    27422488        $registration = seatreg_get_options($code)[0];
    27432489        $structure = SeatregLayoutService::getRoomDataFromLayout($registration->registration_layout);
     2490        $roomNouns = SeatregTerminologyService::getRoomNouns($registration);
     2491        $seatNouns = SeatregTerminologyService::getSeatNouns($registration);
    27442492        $allCorrect = true;
    27452493        $resp = array();
    27462494    $resp['status'] = 'ok';
    2747         $layoutValidation = SeatregLayoutService::validateRoomAndSeatId($structure, $data->roomName, $data->seatId );
     2495        $layoutValidation = SeatregLayoutService::validateRoomAndSeatId($structure, $data->roomName, $data->seatId, null, $roomNouns, $seatNouns );
    27482496
    27492497        if( !$layoutValidation->valid ) {
    … …  
    27712519                        $notBooked = false;
    27722520                        $resp['status'] = 'seat-booked';
    2773                         $resp['text'] = esc_html__('Seat ID ', 'seatreg') . esc_html($data->seatId) . esc_html__(' from room ', 'seatreg') . esc_html($booking->room_name) . esc_html__(' is already booked', 'seatreg');
     2521                        /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat id, %3$s: the word the admin uses for a room, %4$s: Room name */
     2522                        $resp['text'] = sprintf( esc_html__('%1$s ID %2$s from %3$s %4$s is already booked', 'seatreg'), esc_html($seatNouns->singularUpper), esc_html($data->seatId), esc_html($roomNouns->singular), esc_html($booking->room_name) );
    27742523
    27752524                        break;
    … …  
    27922541        $registration = seatreg_get_options($code)[0];
    27932542        $structure = SeatregLayoutService::getRoomDataFromLayout($registration->registration_layout);
     2543        $roomNouns = SeatregTerminologyService::getRoomNouns($registration);
     2544        $seatNouns = SeatregTerminologyService::getSeatNouns($registration);
    27942545        $allCorrect = true;
    27952546    $resp = array();
    27962547    $resp['status'] = 'ok';
    2797         $layoutValidation = SeatregLayoutService::validateRoomAndSeatId($structure, $data->roomName, $data->seatId );
     2548        $layoutValidation = SeatregLayoutService::validateRoomAndSeatId($structure, $data->roomName, $data->seatId, null, $roomNouns, $seatNouns );
    27982549        $customFieldValidation = SeatregDataValidation::validateCustomFieldManagerSubmit($data->editCustomField, $registration->custom_fields, $registration->registration_code);
    27992550
    … …  
    28452596                        $notBooked = false;
    28462597                        $resp['status'] = 'seat-booked';
    2847                         $resp['text'] = esc_html__('Seat ', 'seatreg') . esc_html($data->roomName) . esc_html__(' from room ', 'seatreg') . esc_html($booking->room_name) . esc_html__(' is already booked', 'seatreg');
     2598                        /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat id, %3$s: the word the admin uses for a room, %4$s: Room name */
     2599                        $resp['text'] = sprintf( esc_html__('%1$s ID %2$s from %3$s %4$s is already booked', 'seatreg'), esc_html($seatNouns->singularUpper), esc_html($data->seatId), esc_html($roomNouns->singular), esc_html($booking->room_name) );
    28482600
    28492601                        break;
    … …  
    28672619
    28682620//check if booking room and seat are present in registration layout
    2869 function seatreg_check_room_and_seat($registrationLayout, $bookingRoomName, $bookingSeatNr) {
     2621function seatreg_check_room_and_seat($registrationLayout, $bookingRoomName, $bookingSeatNr, $roomNouns = null, $seatNouns = null) {
    28702622        $layoutLength = count($registrationLayout);
    28712623        $allCorrect = false;
    … …  
    28732625        $searchStatus = '';
    28742626        $errorText = '';
     2627        $roomNoun = $roomNouns ? $roomNouns->singularUpper : SeatregTerminologyService::getRoomNouns()->singularUpper;
     2628        $seatNoun = $seatNouns ? $seatNouns->singularUpper : SeatregTerminologyService::getSeatNouns()->singularUpper;
    28752629
    28762630        for($i = 0; $i < $layoutLength; $i++) {
    28772631                $searchStatus = 'room-searching';
    2878                 $errorText = esc_html__('Room ','seatreg') . esc_html($bookingRoomName) . esc_html__(' dose not exist!', 'seatreg');
     2632                /* translators: %1$s: the word the admin uses for a room, capitalized, %2$s: Room name */
     2633                $errorText = sprintf( esc_html__('%1$s %2$s does not exist!', 'seatreg'), esc_html($roomNoun), esc_html($bookingRoomName) );
    28792634
    28802635                if($registrationLayout[$i]->room->name == $bookingRoomName) {
    28812636                        $searchStatus = 'seat-nr-searching';
    2882                         $errorText = esc_html__('Seat ','seatreg') . esc_html($bookingSeatNr) . esc_html__(' dose not exist in ', 'seatreg') . esc_html($bookingRoomName);
     2637                        /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat number, %3$s: Room name */
     2638                        $errorText = sprintf( esc_html__('%1$s %2$s does not exist in %3$s', 'seatreg'), esc_html($seatNoun), esc_html($bookingSeatNr), esc_html($bookingRoomName) );
    28832639                        $boxLen = count($registrationLayout[$i]->boxes);
    28842640                       
    … …  
    30112767                        custom_footer_text text,
    30122768                        seat_selection_btn_text varchar(255) DEFAULT NULL,
     2769                        room_noun_singular varchar(50) DEFAULT NULL,
     2770                        room_noun_plural varchar(50) DEFAULT NULL,
     2771                        seat_noun_singular varchar(50) DEFAULT NULL,
     2772                        seat_noun_plural varchar(50) DEFAULT NULL,
    30132773                        custom_payments text,
    30142774                        booking_status_page_custom_styles text,
    … …  
    31302890
    31312891        $registration = $wpdb->get_results( $wpdb->prepare(
    3132                 "SELECT a.*, b.paypal_payments, b.paypal_rest_payments, b.stripe_payments, b.custom_payment, b.using_seats, b.using_calendar, b.calendar_dates, b.custom_payments
     2892                "SELECT a.*, b.paypal_payments, b.paypal_rest_payments, b.stripe_payments, b.custom_payment, b.using_seats, b.using_calendar, b.calendar_dates, b.custom_payments, b.room_noun_singular, b.room_noun_plural, b.seat_noun_singular, b.seat_noun_plural
    31332893                FROM $seatreg_db_table_names->table_seatreg AS a
    31342894                INNER JOIN $seatreg_db_table_names->table_seatreg_options AS b
    … …  
    38353595        if( !$registrationNameValidation->valid ) {
    38363596                wp_die( esc_html($registrationNameValidation->errorMessage) );
     3597        }
     3598
     3599        $roomNounSingular = trim( sanitize_text_field( isset($_POST['room-noun-singular']) ? wp_unslash($_POST['room-noun-singular']) : '' ) );
     3600        $roomNounPlural = trim( sanitize_text_field( isset($_POST['room-noun-plural']) ? wp_unslash($_POST['room-noun-plural']) : '' ) );
     3601        $seatNounSingular = trim( sanitize_text_field( isset($_POST['seat-noun-singular']) ? wp_unslash($_POST['seat-noun-singular']) : '' ) );
     3602        $seatNounPlural = trim( sanitize_text_field( isset($_POST['seat-noun-plural']) ? wp_unslash($_POST['seat-noun-plural']) : '' ) );
     3603
     3604        //A lone singular would pair with the default plural and read wrong, and a plural cannot be derived across languages
     3605        if( ($roomNounSingular === '') !== ($roomNounPlural === '') ) {
     3606                wp_die('Both the singular and the plural room noun are required');
     3607        }
     3608
     3609        if( ($seatNounSingular === '') !== ($seatNounPlural === '') ) {
     3610                wp_die('Both the singular and the plural seat noun are required');
     3611        }
     3612
     3613        foreach( array($roomNounSingular, $roomNounPlural, $seatNounSingular, $seatNounPlural) as $noun ) {
     3614                $nounValidation = SeatregDataValidation::validateNoun($noun);
     3615
     3616                if( !$nounValidation->valid ) {
     3617                        wp_die( esc_html($nounValidation->errorMessage) );
     3618                }
    38373619        }
    38383620
    … …  
    41613943                                'payment_completed_set_booking_confirmed_stripe' => $_POST['payment-mark-confirmed-stripe'],
    41623944                                'using_seats' => $_POST['using-seats'],
     3945                                'room_noun_singular' => $roomNounSingular === '' ? null : $roomNounSingular,
     3946                                'room_noun_plural' => $roomNounPlural === '' ? null : $roomNounPlural,
     3947                                'seat_noun_singular' => $seatNounSingular === '' ? null : $seatNounSingular,
     3948                                'seat_noun_plural' => $seatNounPlural === '' ? null : $seatNounPlural,
    41633949                                'email_from_address' => !empty($_POST['email-from']) ? $_POST['email-from'] : null,
    41643950                                'email_background_color' => $customizeEmailColors && !empty($_POST['email-background-color']) ? sanitize_hex_color($_POST['email-background-color']) : null,
    … …  
    43214107        $dataToSend->bookings = $bookings;
    43224108        $dataToSend->uploadedImages = $uploadedImages;
     4109        $dataToSend->roomNouns = SeatregTerminologyService::getRoomNouns( isset($registration[0]) ? $registration[0] : null );
     4110        $dataToSend->seatNouns = SeatregTerminologyService::getSeatNouns( isset($registration[0]) ? $registration[0] : null );
    43234111        $response = new SeatregJsonResponse();
    43244112        $response->setData( $dataToSend);
    … …  
    45204308
    45214309        $resp->echoData();
    4522 
    4523         die();
    4524 }
    4525 
    4526 
    4527 add_action( 'wp_ajax_seatreg_get_room_stats', 'seatreg_get_room_stats_callback' );
    4528 function seatreg_get_room_stats_callback() {
    4529         seatreg_ajax_security_check(SEATREG_MANAGE_BOOKINGS_CAPABILITY);
    4530 
    4531         seatreg_generate_overview_section_html($_POST['data']['target'], sanitize_text_field($_POST['code']), $_POST['data']['calendarDate']);
    45324310
    45334311        die();
  • seatreg/trunk/php/seatreg_shortcode.php

    r3641857 r3693621  
    3232        }
    3333       
    34         $roomQueryParam = '';
     34        $queryArgs = array(
     35            'seatreg' => 'registration',
     36            'c' => $atts['code'],
     37        );
    3538
    3639        if ( !empty($atts['room']) ) {
    … …  
    4750            }
    4851
    49             $roomQueryParam = '&room=' . urlencode( $atts['room'] );
     52            $queryArgs['room'] = $atts['room'];
    5053        }
    5154
    52         $seatregRegistrationUrl = esc_url(SeatregLinksService::getRegistrationURL() . "?seatreg=registration&c=". $atts['code'] . $roomQueryParam);
     55        $queryArgs['page_id'] = SEATREG_PAGE_ID;
     56
     57        //Added as arguments, as the address may already carry the language the page is read in
     58        $seatregRegistrationUrl = esc_url( add_query_arg( $queryArgs, SeatregLinksService::getRegistrationURLInCurrentLanguage() ) );
    5359        $height = (int) esc_attr($atts['height']);
    5460        $mobileHeight = (int) esc_attr($atts['mobile_height']);
    5561        $breakpoint = (int) esc_attr($atts['mobile_max_width']);
    56         $pageId = esc_attr(SEATREG_PAGE_ID);
    5762        $iframeId = esc_attr('seatreg-shortcode-' . uniqid());
    5863        $styleHandle = 'seatreg-inline-' . $iframeId;
    … …  
    7984        wp_add_inline_style($styleHandle, $css);
    8085
    81         return "<iframe id='{$iframeId}' src='{$seatregRegistrationUrl}&page_id={$pageId}'></iframe>";
     86        return "<iframe id='{$iframeId}' src='{$seatregRegistrationUrl}'></iframe>";
    8287    }
    8388    add_shortcode( 'seatreg', 'seatreg_shortcode' );
  • seatreg/trunk/php/seatreg_strings.php

    r3674169 r3693621  
    1010        $translations->emailNotCorrect = esc_html__('Email address is not correct', 'seatreg');
    1111        $translations->somethingWentWrong = esc_html__('Something went wrong. Please try again', 'seatreg');
    12         $translations->selectionIsEmpty = esc_html__('Seat selection is empty', 'seatreg');
    13     $translations->selectionIsEmptyPlace = esc_html__('Place selection is empty', 'seatreg');
    14     $translations->youCanAdd_ = esc_html__('You can add ', 'seatreg');
    15     $translations->_toCartClickTab = esc_html__(' to selection by selecting boxes', 'seatreg');
    16         $translations->toCartClickTab = esc_html__(' to selection by clicking/tabbing them', 'seatreg');
     12        /* translators: %s: the word the admin uses for a seat, capitalized */
     13        $translations->selectionIsEmpty = esc_html__('%s selection is empty', 'seatreg');
     14        /* translators: %s: the word the admin uses for seats, plural */
     15        $translations->youCanAddToSelection = esc_html__('You can add %s to selection by selecting boxes', 'seatreg');
    1716        $translations->regClosedAtMoment = esc_html__('Registration is closed at the moment', 'seatreg');
    1817        $translations->confWillBeSentTo = esc_html__('Confirmation will be sent to:', 'seatreg');
    1918        $translations->confWillBeSentTogmail = esc_html__('Confirmation will be sent to (Gmail):', 'seatreg');
    2019        $translations->gmailReq = esc_html__('Email (Gmail required)', 'seatreg');
    21         $translations->_fromRoom_ = esc_html__(' from room ', 'seatreg');
    22         $translations->_toSelection = esc_html__(' to booking?', 'seatreg');
    23         $translations->_isOccupied = esc_html__(' is occupied', 'seatreg');
    24         $translations->_isPendingState = esc_html__(' is in pending state', 'seatreg');
     20        /* translators: %1$s: the word the admin uses for a seat, %2$s: the seat number, %3$s: the word the admin uses for a room, %4$s: the room name */
     21        $translations->addSpotFromRoomToBooking = esc_html__('Add %1$s %2$s from %3$s %4$s to booking?', 'seatreg');
     22        /* translators: %1$s: the word the admin uses for a seat, %2$s: the seat number, %3$s: the word the admin uses for a room, %4$s: the room name */
     23        $translations->spotFromRoom = esc_html__('%1$s %2$s from %3$s %4$s', 'seatreg');
     24        /* translators: %s: the word the admin uses for a seat */
     25        $translations->spotIsOccupied = esc_html__('This %s is occupied', 'seatreg');
     26        /* translators: %s: the word the admin uses for a seat */
     27        $translations->spotIsPendingState = esc_html__('This %s is in pending state', 'seatreg');
    2528        $translations->regOwnerNotConfirmed = esc_html__('(registration admin has not confirmed it)', 'seatreg');
    2629        $translations->selectionIsFull = esc_html__('Booking is full', 'seatreg');
    27     $translations->_isAlreadySelected = esc_html__(' is already selected!', 'seatreg');
     30        /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: the seat number */
     31    $translations->spotAlreadySelected = esc_html__('%1$s %2$s is already selected!', 'seatreg');
    2832        $translations->_regUnderConstruction = esc_html__('Under construction', 'seatreg');
    2933        $translations->emptyField = esc_html__('Empty field', 'seatreg');
    3034        $translations->remove = esc_html__('Remove', 'seatreg');
    31         $translations->add_ = esc_html__('Add ', 'seatreg');
    3235        $translations->addToBooking = esc_html__('Add to Booking', 'seatreg');
    33         $translations->openSeatsInRoom_ = esc_html__('Open seats in the room: ', 'seatreg');
    34     $translations->openPlacesInRoom_ = esc_html__('Open places in the room: ', 'seatreg');
    35         $translations->pendingSeatInRoom_ = esc_html__('Pending bookings in the room: ', 'seatreg');
    36         $translations->confirmedSeatInRoom_ = esc_html__('Approved bookings in the room: ', 'seatreg');
    37         $translations->seat = esc_html__('seat', 'seatreg');
    38     $translations->place = esc_html__('place', 'seatreg');
     36        /* translators: %1$s: the word the admin uses for seats, plural, %2$s: the word the admin uses for a room, %3$s: number of open seats */
     37        $translations->openSpotsInRoom = esc_html__('Open %1$s in the %2$s: %3$s', 'seatreg');
     38        /* translators: %1$s: the word the admin uses for a room, %2$s: number of pending bookings */
     39        $translations->pendingBookingsInRoom = esc_html__('Pending bookings in the %1$s: %2$s', 'seatreg');
     40        /* translators: %1$s: the word the admin uses for a room, %2$s: number of approved bookings */
     41        $translations->approvedBookingsInRoom = esc_html__('Approved bookings in the %1$s: %2$s', 'seatreg');
    3942        $translations->firstName = esc_html__('Firstname', 'seatreg');
    4043        $translations->lastName = esc_html__('Lastname', 'seatreg');
    4144        $translations->eMail = esc_html__('Email', 'seatreg');
    42         $translations->this_ = esc_html__('This ', 'seatreg');
    43     $translations->_selected = esc_html__(' selected', 'seatreg');
    44     $translations->_seatSelected = esc_html__(' seat selected', 'seatreg');
    45     $translations->_seatsSelected = esc_html__(' seats selected', 'seatreg');
    46     $translations->_placeSelected = esc_html__(' place selected', 'seatreg');
    47     $translations->_placesSelected = esc_html__(' places selected', 'seatreg');
     45        /* translators: %1$s: number of selected seats, %2$s: the word the admin uses for a seat, singular or plural to match the number */
     46    $translations->spotsSelected = esc_html__('%1$s %2$s selected', 'seatreg');
    4847    $translations->bookingsConfirmed = esc_html__('Your booking is approved', 'seatreg');
    4948    $translations->bookingsConfirmedPending = esc_html__('Your booking is now in pending state. Registration admin needs to approve it', 'seatreg');
    50     $translations->selectingGuide = esc_html__('Select a seat you want to add to booking', 'seatreg');
    51     $translations->selectingGuidePlace = esc_html__('Select a place you want to add to booking', 'seatreg');
     49    /* translators: %s: the word the admin uses for a seat */
     50    $translations->selectingGuide = esc_html__('Select a %s you want to add to booking', 'seatreg');
    5251    $translations->Booked = esc_html__('Booked', 'seatreg');
    5352    $translations->Pending = esc_html__('Pending', 'seatreg');
    54     $translations->maxSeatsToAdd = esc_html__('Total seats you can add to booking is ', 'seatreg');
    55     $translations->maxPlacesToAdd = esc_html__('Total places you can add to booking is ', 'seatreg');
    56     $translations->seatCosts_ = esc_html__('Booking this seat costs ', 'seatreg');
    57     $translations->placeCosts_ = esc_html__('Booking this place costs ', 'seatreg');
     53    /* translators: %1$s: the word the admin uses for seats, plural, %2$s: the maximum number */
     54    $translations->maxSpotsToAdd = esc_html__('Total %1$s you can add to booking is %2$s', 'seatreg');
     55    /* translators: %1$s: the word the admin uses for a seat, %2$s: the price */
     56    $translations->spotCosts = esc_html__('Booking this %1$s costs %2$s', 'seatreg');
    5857    $translations->bookingTotalCostIs_ = esc_html__('Booking total cost is ', 'seatreg');
    5958    $translations->receiptSent = esc_html__('Booking receipt has been sent to your email', 'seatreg');
    … …  
    6160    $translations->yes = esc_html__('Yes', 'seatreg');
    6261    $translations->no = esc_html__('No', 'seatreg');
    63     $translations->seatIsLocked = esc_html__('Seat is locked', 'seatreg');
    64     $translations->placeIsLocked = esc_html__('Place is locked', 'seatreg');
     62    /* translators: %s: the word the admin uses for a seat, capitalized */
     63    $translations->spotIsLocked = esc_html__('%s is locked', 'seatreg');
    6564    $translations->pleaseEnterPassword = esc_html__('Please enter password', 'seatreg');
    6665    $translations->passwordNotCorrect = esc_html__('Password is not correct', 'seatreg');
    … …  
    8180function seatreg_generate_admin_strings() {
    8281    $translations = new stdClass();
     82    $translations->overviewConfirmed = esc_html__('Confirmed', 'seatreg');
     83    $translations->overviewPending = esc_html__('Pending', 'seatreg');
     84    $translations->overviewOpen = esc_html__('Open', 'seatreg');
    8385    $translations->hoverDeleteSuccess = esc_html__('Hover text deleted', 'seatreg');
    8486    $translations->hoverTextAdded = esc_html__('Hover text added', 'seatreg');
    … …  
    8688    $translations->legendColorChanged = esc_html__('Legend color changed', 'seatreg');
    8789    $translations->buildingGridUpdated = esc_html__('Building grid updated', 'seatreg');
    88     $translations->roomNameChanged = esc_html__('Room name changed', 'seatreg');
    89     $translations->roomNameSet = esc_html__('New room added', 'seatreg');
    90     $translations->roomNotExist = esc_html__('Room does not exist', 'seatreg');
    91     $translations->seatNotExist = esc_html__('Seat does not exist', 'seatreg');
    92     $translations->seatIdNotExist = esc_html__('Seat id dose not exist', 'seatreg');
    93     $translations->seatAlreadyBookedPending = esc_html__('Seat is already booked/pending', 'seatreg');
     90    /* translators: %s: the word the admin uses for a room, capitalized */
     91    $translations->roomNameChanged = esc_html( _x('%s name changed', 'layout builder confirmation after renaming a room', 'seatreg') );
     92    /* translators: %s: the word the admin uses for a room */
     93    $translations->roomNameSet = esc_html__('New %s added', 'seatreg');
     94    /* translators: %s: the word the admin uses for a room, capitalized */
     95    $translations->roomNotExist = esc_html( _x('%s does not exist', 'booking manager error when the given room name matches nothing', 'seatreg') );
     96    /* translators: %s: the word the admin uses for a seat, capitalized */
     97    $translations->seatIdNotExist = esc_html__('%s id does not exist', 'seatreg');
     98    /* translators: %s: the word the admin uses for a seat, capitalized */
     99    $translations->seatAlreadyBookedPending = esc_html__('%s is already booked/pending', 'seatreg');
    94100    $translations->errorBookingUpdate = esc_html__('Error updating booking', 'seatreg');
    95101    $translations->hoverError = esc_html__('Error while creating hover', 'seatreg');
    … …  
    99105    $translations->legendColorTaken = esc_html__('Legend color is taken. Choose another', 'seatreg');
    100106    $translations->legendAddedTo = esc_html__('Legend added to', 'seatreg');
    101     $translations->oneRoomNeeded = esc_html__('You must have at least one room', 'seatreg');
    102     $translations->alreadyInRoom = esc_html__('Already in this room', 'seatreg');
    103     $translations->allRoomsNeedName = esc_html__('All rooms must have name', 'seatreg');
     107    /* translators: %s: the word the admin uses for a room */
     108    $translations->oneRoomNeeded = esc_html__('You must have at least one %s', 'seatreg');
     109    /* translators: %s: the word the admin uses for a room */
     110    $translations->alreadyInRoom = esc_html__('Already in this %s', 'seatreg');
     111    /* translators: %s: the word the admin uses for rooms, plural */
     112    $translations->allRoomsNeedName = esc_html__('All %s must have name', 'seatreg');
    104113    $translations->illegalCharactersDetec = esc_html__('Illegal characters detected', 'seatreg');
    105114    $translations->illegalCharactersDetecCouponCode = esc_html__('Illegal characters detected in coupon code', 'seatreg');
    … …  
    107116    $translations->illegalCharactersDetecDiscount = esc_html__('Illegal characters detected in discount value', 'seatreg');
    108117    $translations->missingName = esc_html__('Name missing', 'seatreg');
    109     $translations->cantDelRoom_ = esc_html__('You can\'t delete room ', 'seatreg');
    110     $translations->_cantDelRoomBecause = esc_html__(' because it contains pending or confirmed seats. You must remove them with manager first.', 'seatreg');
    111     $translations->roomNameMissing = esc_html__('Room name is missing', 'seatreg');
    112     $translations->roomNameExists = esc_html__('Room name already exists. You must choose another', 'seatreg');
     118    /* translators: %1$s: the word the admin uses for a room, %2$s: the room name */
     119    $translations->cantDeleteRoom = esc_html__('You can\'t delete %1$s %2$s because it contains pending or confirmed seats. You must remove them with manager first.', 'seatreg');
     120    /* translators: %s: the word the admin uses for a room, capitalized */
     121    $translations->roomNameMissing = esc_html( _x('%s name is missing', 'layout builder, empty room name field', 'seatreg') );
     122    /* translators: %s: the word the admin uses for a room, capitalized */
     123    $translations->roomNameExists = esc_html( _x('%s name already exists. You must choose another', 'layout builder, duplicate room name', 'seatreg') );
    113124    $translations->youHaveSelected = esc_html__('You have selected', 'seatreg');
    114125    $translations->_boxesSpanLi = esc_html__(' box/boxes</span></li>', 'seatreg');
    … …  
    123134    $translations->_noSelectBoxToAddLegend = esc_html__(' You have not selected any box/boxes to add legends', 'seatreg');
    124135    $translations->_charRemaining = esc_html__(' characters remaining', 'seatreg');
    125     $translations->deleteRoom_ = esc_html__('Are you sure you want to delete room ', 'seatreg');
     136    /* translators: %1$s: the word the admin uses for a room, %2$s: the room name */
     137    $translations->deleteRoomConfirm = esc_html__('Are you sure you want to delete %1$s %2$s?', 'seatreg');
    126138    $translations->unsavedChanges = esc_html__('Unsaved changes. You sure you want to leave?', 'seatreg');
    127139    $translations->createLegend = esc_html__('Create new legend', 'seatreg');
    … …  
    135147    $translations->box = esc_html__('box', 'seatreg');
    136148    $translations->noBoxesSelected = esc_html__('No boxes selected', 'seatreg');
    137     $translations->pendingSeat = esc_html__('Pending seat', 'seatreg');
    138     $translations->pendingPlace = esc_html__('Pending place', 'seatreg');
    139     $translations->confirmedSeat = esc_html__('Approved seat', 'seatreg');
    140     $translations->confirmedPlace= esc_html__('Approved place', 'seatreg');
     149    /* translators: %s: the word the admin uses for a seat */
     150    $translations->pendingSeat = esc_html__('Pending %s', 'seatreg');
     151    /* translators: %s: the word the admin uses for a seat */
     152    $translations->confirmedSeat = esc_html__('Approved %s', 'seatreg');
    141153    $translations->save = esc_html__('Save', 'seatreg');
    142154    $translations->saving = esc_html__('Saving...', 'seatreg');
    143155    $translations->saved = esc_html__('Saved', 'seatreg');
    144     $translations->room = esc_html__('room', 'seatreg');
    145156    $translations->bookingUpdated = esc_html__('Booking updated', 'seatreg');
    146157    $translations->notSet = esc_html__('Not set', 'seatreg');
    … …  
    152163    $translations->pleaseAddAtLeastOneOption = esc_html__('Please add at least one option', 'seatreg');
    153164    $translations->nameAlreadyUsed = esc_html__('Name already used', 'seatreg');
    154     $translations->noBgImageInRoom = esc_html__('Current room does not have background image', 'seatreg');
    155     $translations->removeFromRoom = esc_html__('Remove from room', 'seatreg');
     165    /* translators: %s: the word the admin uses for a room */
     166    $translations->noBgImageInRoom = esc_html__('Current %s does not have background image', 'seatreg');
     167    /* translators: %s: the word the admin uses for a room */
     168    $translations->removeFromRoom = esc_html( _x('Remove from %s', 'layout builder, remove the background image from the room', 'seatreg') );
    156169    $translations->choosePictureToUpload = esc_html__('Choose a picture to upload', 'seatreg');
    157170    $translations->imageNameIllegalChar = esc_html__('Image name contains illegal characters', 'seatreg');
    158     $translations->addToRoomBackground = esc_html__('Add to room background', 'seatreg');
     171    /* translators: %s: the word the admin uses for a room */
     172    $translations->addToRoomBackground = esc_html__('Add to %s background', 'seatreg');
    159173    $translations->remove = esc_html__('Remove', 'seatreg');
    160174    $translations->showPendingBookings = esc_html__('Show pending bookings', 'seatreg');
    … …  
    175189    $translations->pleaseProvideStripeApiSecretKey = esc_html__('Please provide Stripe API secret key', 'seatreg');
    176190    $translations->pricesAdded = esc_html__('Prices added', 'seatreg');
    177     $translations->noSeatsSelected = esc_html__('No seats/places selected!', 'seatreg');
     191    /* translators: %s: the word the admin uses for seats, plural */
     192    $translations->noSeatsSelected = esc_html__('No %s selected!', 'seatreg');
    178193    $translations->emailNotCorrect = esc_html__('Email address is not correct', 'seatreg');
    179194    $translations->emailFromNotCorrect = esc_html__('Email FROM address is not correct', 'seatreg');
    … …  
    188203    $translations->bookingPermanentlyDeleted = esc_html__('Booking permanently deleted', 'seatreg');
    189204    $translations->newBookingWasAddedRefreshingThaPage = esc_html__('Booking was added. Page will refresh in a second', 'seatreg');
    190     $translations->duplicateSeatDetected = esc_html__('Duplicate seat detected!', 'seatreg');
     205    /* translators: %s: the word the admin uses for a seat */
     206    $translations->duplicateSeatDetected = esc_html__('Duplicate %s detected!', 'seatreg');
    191207    $translations->emailTemplateNotCorrect = esc_html__('Email template is missing required keywords', 'seatreg');
    192208    $translations->approvedBookingEmailTemplateIllegalCharacter = esc_html__('The approved booking email template contains disallowed characters.', 'seatreg');
    193209    $translations->pendingBookingEmailTemplateIllegalCharacter = esc_html__('The pending booking email template contains disallowed characters.', 'seatreg');
    194210    $translations->emailVerificationEmailTemplateIllegalCharacter = esc_html__('The email verification template contains disallowed characters.', 'seatreg');
    195     $translations->lockSeat = esc_html__('Lock seat', 'seatreg');
     211    /* translators: %s: the word the admin uses for a seat */
     212    $translations->lockSeat = esc_html__('Lock %s', 'seatreg');
    196213    $translations->setPassword = esc_html__('Set password', 'seatreg');
    197214    $translations->changesApplied = esc_html__('Changes applied', 'seatreg');
    … …  
    227244    $translations->bookingMainEmail = esc_html__('Booking main email', 'seatreg');
    228245    $translations->editEmailNotValid = esc_html__('Provided email address is not valid', 'seatreg');
    229     $translations->multiBookingMailEmailEditDesc = esc_html__('Primary contact email if more than one seat is booked', 'seatreg');
    230     $translations->roomDescriptionSet = esc_html__('Room description changed', 'seatreg');
     246    /* translators: %s: the word the admin uses for a seat */
     247    $translations->multiBookingMailEmailEditDesc = esc_html__('Primary contact email if more than one %s is booked', 'seatreg');
     248    /* translators: %s: the word the admin uses for a room, capitalized */
     249    $translations->roomDescriptionSet = esc_html( _x('%s description changed', 'layout builder confirmation after editing a room description', 'seatreg') );
    231250    $translations->primaryEmailValidationFailed = esc_html__('Booking primary email validation failed', 'seatreg');
    232251    $translations->pleaseEnterBookingPrimaryEmail = esc_html__('Please enter booking primary email', 'seatreg');
    … …  
    241260    $translations->flowGroupAfter = esc_html__('After submitting', 'seatreg');
    242261    $translations->flowJumpToSetting = esc_html__('Go to this setting', 'seatreg');
     262    //The summary previews the form as it is typed, so it needs the words the seats checkbox would pick
    243263    $translations->flowSeatSingular = esc_html__('seat', 'seatreg');
    244264    $translations->flowSeatPlural = esc_html__('seats', 'seatreg');
    … …  
    250270    $translations->flowPassword = esc_html__('Visitors must enter the access password to view it.', 'seatreg');
    251271    $translations->flowRequireLogin = esc_html__('Only visitors logged in to your site can book.', 'seatreg');
    252     /* translators: %1$d: number of bookings, %2$s: seats or places */
     272    /* translators: %1$d: number of bookings, %2$s: the word the admin uses for seats, plural */
    253273    $translations->flowWpBookingLimit = esc_html__('Each logged-in user can make at most %1$d separate bookings (a single booking can include several %2$s).', 'seatreg');
    254     /* translators: %1$d: number of seats, %2$s: seats or places */
     274    /* translators: %1$d: number of seats, %2$s: the word the admin uses for seats, plural */
    255275    $translations->flowWpSeatLimit = esc_html__('Across all their bookings, each logged-in user can book at most %1$d %2$s.', 'seatreg');
    256276    $translations->flowDateWindowBoth = esc_html__('Bookings can only be made within the registration\'s scheduled start and end dates.', 'seatreg');
    … …  
    265285    $translations->calendarNoDatesSelected = esc_html__('No dates selected yet', 'seatreg');
    266286    $translations->calendarRemoveDate = esc_html__('Remove date', 'seatreg');
    267     /* translators: %s: seats or places */
     287    /* translators: %s: the word the admin uses for seats, plural */
    268288    $translations->flowSelect = esc_html__('Visitors select %s on the map.', 'seatreg');
    269     /* translators: %1$s: seats or places, %2$d: maximum number per booking */
     289    /* translators: %1$s: the word the admin uses for seats, plural, %2$d: maximum number per booking */
    270290    $translations->flowSelectMax = esc_html__('Visitors select %1$s on the map, up to %2$d per booking.', 'seatreg');
    271     /* translators: %1$s: seats or places, %2$s: comma-separated list of shown details */
     291    /* translators: %1$s: the word the admin uses for seats, plural, %2$s: comma-separated list of shown details */
    272292    $translations->flowShowBookingData = esc_html__('Already-booked %1$s publicly display the booking details you have chosen to show (%2$s).', 'seatreg');
    273293    $translations->flowShowBookingDataFullName = esc_html__('full name', 'seatreg');
    274     /* translators: %s: seat or place */
     294    /* translators: %s: the word the admin uses for a seat */
    275295    $translations->flowAutoDialog = esc_html__('The booking form opens automatically as soon as a %s is selected.', 'seatreg');
    276     /* translators: %s: seats or places */
     296    /* translators: %s: the word the admin uses for seats, plural */
    277297    $translations->flowManualDialog = esc_html__('After choosing %s, visitors open the selection menu to complete their booking.', 'seatreg');
    278     /* translators: %s: seat or place */
     298    /* translators: %s: the word the admin uses for a seat */
    279299    $translations->flowOnePersonCheckout = esc_html__('Booking details are entered once and applied to every %s.', 'seatreg');
    280     /* translators: %s: seat or place */
     300    /* translators: %s: the word the admin uses for a seat */
    281301    $translations->flowPerSeatCheckout = esc_html__('Booking details are entered for each %s.', 'seatreg');
    282302    $translations->flowRequireName = esc_html__('A full name (first and last) is required.', 'seatreg');
    283303    $translations->flowGmailRequired = esc_html__('A Gmail address is required.', 'seatreg');
    284     /* translators: %1$d: maximum number of bookings per email, %2$s: seats or places */
     304    /* translators: %1$d: maximum number of bookings per email, %2$s: the word the admin uses for seats, plural */
    285305    $translations->flowEmailLimit = esc_html__('A booking\'s main contact email can be used for at most %1$d bookings (a single booking can include several %2$s).', 'seatreg');
    286306    $translations->flowCustomFields = esc_html__('Bookers also fill in the custom fields you have created, which are required by default.', 'seatreg');
  • seatreg/trunk/php/services/SeatregBookingService.php

    r3641857 r3693621  
    149149            return $customField->label;
    150150        }, is_array( $enteredCustomFieldData) ? $enteredCustomFieldData : [] );
    151         $spotName = $registration->using_seats ? __('Seat', 'seatreg') : __('Place', 'seatreg');
     151        $spotName = SeatregTerminologyService::getSeatNouns($registration)->singularUpper;
     152        $roomName = SeatregTerminologyService::getRoomNouns($registration)->singularUpper;
    152153        $hasCalendarDate = (boolean)$bookings[0]->calendar_date;
    153154        $roomsLayout = SeatregLayoutService::getRoomDataFromLayout($registration->registration_layout ?? null);
    … …  
    159160
    160161        $hasLegends = count(array_filter($seatLegends)) > 0;
    161         $headers = array( __('Name', 'seatreg'), $spotName, __('Room', 'seatreg') );
     162        $headers = array( __('Name', 'seatreg'), $spotName, $roomName );
    162163
    163164        if($hasLegends) {
    … …  
    182183                array( 'label' => __('Name', 'seatreg'), 'value' => $booking->first_name . ' ' . $booking->last_name ),
    183184                array( 'label' => $spotName, 'value' => $booking->seat_nr ),
    184                 array( 'label' => __('Room', 'seatreg'), 'value' => $booking->room_name ),
     185                array( 'label' => $roomName, 'value' => $booking->room_name ),
    185186            );
    186187
    … …  
    313314
    314315        return array(
    315             'spotName' => $bookingData->using_seats ? __('Seat', 'seatreg') : __('Place', 'seatreg'),
     316            'spotName' => SeatregTerminologyService::getSeatNouns($bookingData)->singularUpper,
    316317            'rows' => $rows,
    317318            'total' => ( $couponsEnabled ? self::applyCouponDiscountToTotalCost($totalCost, $appliedCoupon) : $totalCost ) . ' ' . $bookingData->paypal_currency_code,
  • seatreg/trunk/php/services/SeatregCSVService.php

    r3624498 r3693621  
    1717    private $roomData;
    1818    private $existingBookings;
     19    private $roomNouns;
     20    private $seatNouns;
    1921
    2022    public function __construct($code) {
    … …  
    2325        $this->roomData = SeatregLayoutService::getRoomDataFromLayout($this->registrationData->registration_layout);
    2426        $this->existingBookings = SeatregBookingRepository::getAllConfirmedAndApprovedBookingsByRegistrationCode($this->seatregCode);
     27        $options = SeatregOptionsRepository::getOptionsByRegistrationCode($this->seatregCode);
     28        $this->roomNouns = SeatregTerminologyService::getRoomNouns($options);
     29        $this->seatNouns = SeatregTerminologyService::getSeatNouns($options);
    2530    }
    2631
    … …  
    6166            }
    6267            $obj->room_name = $roomName;
    63             $seatAndRoomValidation = SeatregLayoutService::validateRoomAndSeatId($this->roomData, $roomName, $row[SEATREG_CSV_COL_SEAT_ID], $row[SEATREG_CSV_COL_SEAT_NR]);
     68            $seatAndRoomValidation = SeatregLayoutService::validateRoomAndSeatId($this->roomData, $roomName, $row[SEATREG_CSV_COL_SEAT_ID], $row[SEATREG_CSV_COL_SEAT_NR], $this->roomNouns, $this->seatNouns);
    6469            if( !$seatAndRoomValidation->valid ) {
    6570                $obj->is_valid = false;
  • seatreg/trunk/php/services/SeatregImportService.php

    r3624498 r3693621  
    66    private $roomData;
    77    private $existingBookings;
     8    private $roomNouns;
     9    private $seatNouns;
    810    private $failedImports = array();
    911    private $successfulImports = array();
    … …  
    1517        $this->roomData = SeatregLayoutService::getRoomDataFromLayout($this->registrationData->registration_layout);
    1618        $this->existingBookings = SeatregBookingRepository::getAllConfirmedAndApprovedBookingsByRegistrationCode($this->seatregCode);
     19        $options = SeatregOptionsRepository::getOptionsByRegistrationCode($this->seatregCode);
     20        $this->roomNouns = SeatregTerminologyService::getRoomNouns($options);
     21        $this->seatNouns = SeatregTerminologyService::getSeatNouns($options);
    1722    }
    1823
    … …  
    3237        }
    3338
    34         $seatAndRoomValidation = SeatregLayoutService::validateRoomAndSeatId($this->roomData, $roomName, $bookingData->seat_id, $bookingData->seat_nr);
     39        $seatAndRoomValidation = SeatregLayoutService::validateRoomAndSeatId($this->roomData, $roomName, $bookingData->seat_id, $bookingData->seat_nr, $this->roomNouns, $this->seatNouns);
    3540        if( !$seatAndRoomValidation->valid ) {
    3641            $validation->is_valid = false;
  • seatreg/trunk/php/services/SeatregLayoutService.php

    r3641857 r3693621  
    7373    }
    7474
    75     public static function validateRoomAndSeatId($layout, $bookingRoomName, $bookingSeatId, $seatNr = null) {
     75    public static function validateRoomAndSeatId($layout, $bookingRoomName, $bookingSeatId, $seatNr = null, $roomNouns = null, $seatNouns = null) {
    7676        $status = (object) [
    7777            'valid' => false,
    … …  
    7979            'errorText' => ''
    8080        ];
     81        $roomNoun = $roomNouns ? $roomNouns->singularUpper : SeatregTerminologyService::getRoomNouns()->singularUpper;
     82        $seatNoun = $seatNouns ? $seatNouns->singularUpper : SeatregTerminologyService::getSeatNouns()->singularUpper;
    8183
    8284        foreach( $layout as $layoutData ) {
    8385            $room = $layoutData->room;
    8486            $status->searchStatus = 'room-searching';
    85             /* translators: %s: Room name */
    86             $status->errorText = sprintf( esc_html__('Room %s does not exist!', 'seatreg'), esc_html($bookingRoomName) );
     87            /* translators: %1$s: the word the admin uses for a room, capitalized, %2$s: Room name */
     88            $status->errorText = sprintf( esc_html__('%1$s %2$s does not exist!', 'seatreg'), esc_html($roomNoun), esc_html($bookingRoomName) );
    8789   
    8890            if( $room->name == $bookingRoomName ) {
    … …  
    9092
    9193                if ($seatNr !== null) {
    92                     /* translators: %1$s: Seat ID, %2$s: Seat number, %3$s: Room name */
    93                     $status->errorText = sprintf(esc_html__('Seat id %1$s with number %2$s does not exist in %3$s', 'seatreg'), esc_html($bookingSeatId), esc_html($seatNr), esc_html($bookingRoomName));
     94                    /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat ID, %3$s: Seat number, %4$s: Room name */
     95                    $status->errorText = sprintf(esc_html__('%1$s id %2$s with number %3$s does not exist in %4$s', 'seatreg'), esc_html($seatNoun), esc_html($bookingSeatId), esc_html($seatNr), esc_html($bookingRoomName));
    9496                } else {
    95                     /* translators: %1$s: Seat ID, %2$s: Room name */
    96                     $status->errorText = sprintf(esc_html__('Seat id %1$s does not exist in %2$s', 'seatreg'), esc_html($bookingSeatId), esc_html($bookingRoomName));
     97                    /* translators: %1$s: the word the admin uses for a seat, capitalized, %2$s: Seat ID, %3$s: Room name */
     98                    $status->errorText = sprintf(esc_html__('%1$s id %2$s does not exist in %3$s', 'seatreg'), esc_html($seatNoun), esc_html($bookingSeatId), esc_html($bookingRoomName));
    9799                }
    98100               
    … …  
    265267
    266268    public static function getSeatsStats($struct, $bronRegistrations, $takenRegistrations) {
    267         $registration = json_decode($struct);
     269        $registration = $struct ? json_decode($struct) : null;
    268270        if(!isset($registration->roomData)) {
    269271            return [];
    … …  
    325327            }
    326328   
     329            //roomOpenSeats counts from every bookable seat, roomOpenNoStatusSeats only from the ones left
     330            //without a status - the basis the registration wide openSeats below is counted on
    327331            $roomsInfo[] = array(
    328332                'roomUuid' => $regStructure[$i]->room->uuid,
     333                'roomName' => $regStructure[$i]->room->name,
    329334                'roomSeatsTotal' => $roomRegSeats,
    330335                'roomOpenSeats' => $roomRegSeats - $roomTakenSeats - $roomBronSeats,
     336                'roomOpenNoStatusSeats' => $roomOpenSeats - $roomTakenSeats - $roomBronSeats,
    331337                'roomTakenSeats' => $roomTakenSeats,
    332338                'roomBronSeats' => $roomBronSeats,
  • seatreg/trunk/php/services/SeatregLinksService.php

    r3040613 r3693621  
    66
    77class SeatregLinksService {
    8     public static function getRegistrationURL() {   
     8    public static function getRegistrationURL() {
    99        return get_site_url() . '/seatreg';
    1010    }
     11
     12    /**
     13     *
     14     * The registration address in the language the visitor is reading, so a registration
     15     * embedded in a page opens in that page's language. How a language is written into an
     16     * address is the translation plugin's own business, so it is left to write it.
     17     *
     18     * @return string
     19     *
     20     */
     21    public static function getRegistrationURLInCurrentLanguage() {
     22        $url = self::getRegistrationURL();
     23
     24        if( function_exists('PLL') && isset(PLL()->links_model) && isset(PLL()->curlang) ) {
     25            return PLL()->links_model->add_language_to_link($url, PLL()->curlang);
     26        }
     27
     28        if( defined('ICL_LANGUAGE_CODE') ) {
     29            return apply_filters('wpml_permalink', $url, ICL_LANGUAGE_CODE);
     30        }
     31
     32        return $url;
     33    }
    1134}
  • seatreg/trunk/php/views/modals/add-booking-modal.php

    r3496616 r3693621  
    2626                                                <label>
    2727                                                        <h5>
    28                                                                 <?php $usingSeats ? esc_html_e('Seat ID', 'seatreg') : esc_html_e('Place ID', 'seatreg'); ?>
    29                                                                 <i class="fa fa-question-circle seatreg-ui-tooltip" aria-hidden="true" title="<?php $usingSeats ? esc_html_e('ID can be seen in map-editor when hovering seats. Or you can use seat ID lookup', 'seatreg') : esc_html_e('ID can be seen in map-editor when hovering places', 'seatreg'); ?>"></i>
     28                                                                <?php echo esc_html( sprintf( __('%s ID', 'seatreg'), $seatNouns->singularUpper ) ); ?>
     29                                                                <i class="fa fa-question-circle seatreg-ui-tooltip" aria-hidden="true" title="<?php echo esc_attr( sprintf( __('ID can be seen in map-editor when hovering %1$s. Or you can use %2$s ID lookup', 'seatreg'), $seatNouns->plural, $seatNouns->singular ) ); ?>"></i>
    3030                                                        </h5>
    3131                                                        <input type="text" name="seat-id[]" autocomplete="off"/>
    … …  
    3636                                                <label>
    3737                                                        <h5>
    38                                                                 <?php esc_html_e('Room', 'seatreg'); ?>
     38                                                                <?php echo esc_html($roomNouns->singularUpper); ?>
    3939                                                        </h5>
    4040                                                        <select name="room[]">
    … …  
    8585                                <div class="seat-operations">
    8686                                        <div class="seat-operation" id="add-modal-add-seat">
    87                                                 <?php $usingSeats ? esc_html_e('Add seat', 'seatreg') : esc_html_e('Add place', 'seatreg'); ?>
     87                                                <?php echo esc_html( sprintf( _x('Add %s', 'booking manager button that adds one more seat to the booking being added', 'seatreg'), $seatNouns->singular ) ); ?>
    8888                                                <i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i>
    8989                                        </div>
    9090                                        <div class="seat-operation" id="add-modal-remove-seat">
    91                                                 <?php $usingSeats ? esc_html_e('Remove seat', 'seatreg') : esc_html_e('Remove place', 'seatreg'); ?>
     91                                                <?php echo esc_html( sprintf( _x('Remove %s', 'booking manager button that removes a seat from the booking being added', 'seatreg'), $seatNouns->singular ) ); ?>
    9292                                                <i class="fa fa-minus-circle fa-lg" aria-hidden="true"></i>
    9393                                        </div>
  • seatreg/trunk/php/views/modals/booking-edit-modal.php

    r3496616 r3693621  
    2121                                <label for="edit-seat">
    2222                                        <h5>
    23                                                 <?php $usingSeats ? esc_html_e('Seat id', 'seatreg') : esc_html_e('Place id', 'seatreg'); ?>
     23                                                <?php echo esc_html( sprintf( __('%s id', 'seatreg'), $seatNouns->singularUpper ) ); ?>
    2424                                        </h5>
    2525                                </label>
    26                                 <i class="fa fa-question-circle seatreg-ui-tooltip" aria-hidden="true" title="<?php $usingSeats ? esc_html_e('ID can be seen in map-editor when hovering seats', 'seatreg') : esc_html_e('ID can be seen in map-editor when hovering places', 'seatreg'); ?>"></i>
     26                                <i class="fa fa-question-circle seatreg-ui-tooltip" aria-hidden="true" title="<?php echo esc_attr( sprintf( __('ID can be seen in map-editor when hovering %s', 'seatreg'), $seatNouns->plural ) ); ?>"></i>
    2727                                <br>
    2828                                <input type="text" id="edit-seat" name="seat-id" autocomplete="off"/></label> <span id="edit-seat-error"></span>
    … …  
    3030                       
    3131                        <div class="edit-modal-input-wrap">
    32                                 <label for="edit-room"><h5><?php esc_html_e('Room', 'seatreg'); ?></h5></label><br>
     32                                <label for="edit-room"><h5><?php echo esc_html($roomNouns->singularUpper); ?></h5></label><br>
    3333                                <input type="text" id="edit-room" name="room" autocomplete="off"/> <span id="edit-room-error"></span>
    3434                        </div>
  • seatreg/trunk/php/views/modals/seat-id-modal.php

    r3496616 r3693621  
    55    <div class="modal-content">
    66      <div class="modal-header">
    7                 <h4 class="modal-title"><?php esc_html_e('Seat ID lookup', 'seatreg'); ?></h4>
     7                <h4 class="modal-title"><?php echo esc_html( sprintf( _x('%s ID lookup', 'booking manager dialog title for looking up a seat id', 'seatreg'), $seatNouns->singularUpper ) ); ?></h4>
    88        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only"><?php esc_html_e('Close', 'seatreg'); ?></span></button>
    99      </div>
    … …  
    3737
    3838                                                        <button class="btn btn-outline-secondary btn-sm" data-action="select-id" data-seat-id="<?php echo esc_attr($box->id); ?>" data-seat-price="<?php echo esc_attr(json_encode($price)); ?>" data-seat-number="<?php echo esc_attr($seatNumber); ?>" data-room-name="<?php echo esc_attr($roomData->room->name); ?>">
    39                                                                 <?php echo esc_html('Select ID', 'seatreg'); ?>
     39                                                                <?php esc_html_e('Select ID', 'seatreg'); ?>
    4040                                                        </button>
    4141                                                <?php endif; ?>
    … …  
    4343                                </div>
    4444                                <?php if($openSeatCounter === 0): ?>
    45                                         <div class="alert alert-info"><?php echo sprintf(esc_html('No open seats in %s', 'seatreg'), esc_html($roomData->room->name)); ?></div>
     45                                        <div class="alert alert-info"><?php
     46                                                /* translators: %1$s: the word the admin uses for seats, plural, %2$s: Room name */
     47                                                echo sprintf(esc_html__('No open %1$s in %2$s', 'seatreg'), esc_html($seatNouns->plural), esc_html($roomData->room->name));
     48                                        ?></div>
    4649                                <?php endif; ?>
    4750                        <?php endforeach; ?>
  • seatreg/trunk/php/views/modals/shortcode-modal.php

    r3641857 r3693621  
    1515                <code class="shortcode-example">[seatreg code=<?php echo esc_html($registrationCode); ?> height=600 mobile_height=500 mobile_max_width=600]</code>
    1616                <?php if( count($rooms) ) : ?>
    17                     <p class="shortcode-instructions"><?php esc_html_e("You can choose which room the registration opens on.", "seatreg"); ?></p>
     17                    <p class="shortcode-instructions"><?php
     18                        /* translators: %s: the word the admin uses for a room */
     19                        echo esc_html( sprintf( __('You can choose which %s the registration opens on. The attribute is always named room.', 'seatreg'), $roomNouns->singular ) );
     20                    ?></p>
    1821                    <code class="shortcode-example">[seatreg code=<?php echo esc_html($registrationCode); ?> height=600 room="<?php echo esc_html($rooms[0]->room->name); ?>"]</code>
    1922                    <p class="shortcode-instructions">
    20                         <?php esc_html_e("Available rooms", "seatreg"); ?>:
     23                        <?php
     24                            /* translators: %s: the word the admin uses for rooms, plural */
     25                            echo esc_html( sprintf( __('Available %s', 'seatreg'), $roomNouns->plural ) );
     26                        ?>:
    2127                        <?php
    2228                            $roomNames = array();
  • seatreg/trunk/php/views/parts/donation-flowers.php

    r3680221 r3693621  
    1 <div class="seatreg-flower-container" style="--flower-size: 12px; --flower-delay: 0s; --flower-opacity: 0.1; top:42px;left:46px">
    2     <div class="seatreg-flower-droplet seatreg-flower-droplet-1"></div>
    3     <div class="seatreg-flower-droplet seatreg-flower-droplet-2"></div>
    4     <div class="seatreg-flower-droplet seatreg-flower-droplet-3"></div>
    5     <div class="seatreg-flower-droplet seatreg-flower-droplet-4"></div>
    6     <div class="seatreg-flower-droplet seatreg-flower-droplet-5"></div>
    7     <div class="seatreg-flower-droplet seatreg-flower-droplet-6"></div>
    8     <div class="seatreg-flower-droplet seatreg-flower-droplet-7"></div>
    9     <div class="seatreg-flower-droplet seatreg-flower-droplet-8"></div>
    10     <div class="seatreg-flower-droplet seatreg-flower-droplet-9"></div>
    11     <div class="seatreg-flower-droplet seatreg-flower-droplet-10"></div>
     1<?php
     2if(!defined('ABSPATH')) exit;
     3
     4$seatreg_flowers = array(
     5        array( 'size' => '12px', 'delay' => '0s', 'position' => 'top: 24%; left: 24px;' ),
     6        array( 'size' => '18px', 'delay' => '1s', 'position' => 'top: 12px; right: 64px;' ),
     7        array( 'size' => '14px', 'delay' => '2s', 'position' => 'bottom: 26%; right: 48px;' ),
     8        array( 'size' => '10px', 'delay' => '4s', 'position' => 'bottom: 0; left: 16px;' ),
     9);
     10?>
     11
     12<div class="seatreg-flower-layer" aria-hidden="true">
     13        <?php foreach($seatreg_flowers as $seatreg_flower) : ?>
     14                <div class="seatreg-flower-container" style="--flower-size: <?php echo esc_attr($seatreg_flower['size']); ?>; --flower-delay: <?php echo esc_attr($seatreg_flower['delay']); ?>; --flower-opacity: 0.1; <?php echo esc_attr($seatreg_flower['position']); ?>">
     15                        <?php for($seatreg_droplet = 1; $seatreg_droplet <= 10; $seatreg_droplet++) : ?>
     16                                <div class="seatreg-flower-droplet seatreg-flower-droplet-<?php echo esc_attr($seatreg_droplet); ?>"></div>
     17                        <?php endfor; ?>
     18                </div>
     19        <?php endforeach; ?>
    1220</div>
    13 
    14 <div class="seatreg-flower-container" style="--flower-size: 18px; --flower-delay: 1s; --flower-opacity: 0.1; top:0px; left:380px">
    15     <div class="seatreg-flower-droplet seatreg-flower-droplet-1"></div>
    16     <div class="seatreg-flower-droplet seatreg-flower-droplet-2"></div>
    17     <div class="seatreg-flower-droplet seatreg-flower-droplet-3"></div>
    18     <div class="seatreg-flower-droplet seatreg-flower-droplet-4"></div>
    19     <div class="seatreg-flower-droplet seatreg-flower-droplet-5"></div>
    20     <div class="seatreg-flower-droplet seatreg-flower-droplet-6"></div>
    21     <div class="seatreg-flower-droplet seatreg-flower-droplet-7"></div>
    22     <div class="seatreg-flower-droplet seatreg-flower-droplet-8"></div>
    23     <div class="seatreg-flower-droplet seatreg-flower-droplet-9"></div>
    24     <div class="seatreg-flower-droplet seatreg-flower-droplet-10"></div>
    25 </div>
    26 
    27 <div class="seatreg-flower-container" style="--flower-size: 14px; --flower-delay: 2s; --flower-opacity: 0.1; top:260px; left:400px">
    28     <div class="seatreg-flower-droplet seatreg-flower-droplet-1"></div>
    29     <div class="seatreg-flower-droplet seatreg-flower-droplet-2"></div>
    30     <div class="seatreg-flower-droplet seatreg-flower-droplet-3"></div>
    31     <div class="seatreg-flower-droplet seatreg-flower-droplet-4"></div>
    32     <div class="seatreg-flower-droplet seatreg-flower-droplet-5"></div>
    33     <div class="seatreg-flower-droplet seatreg-flower-droplet-6"></div>
    34     <div class="seatreg-flower-droplet seatreg-flower-droplet-7"></div>
    35     <div class="seatreg-flower-droplet seatreg-flower-droplet-8"></div>
    36     <div class="seatreg-flower-droplet seatreg-flower-droplet-9"></div>
    37     <div class="seatreg-flower-droplet seatreg-flower-droplet-10"></div>
    38 </div>
    39 
    40 <div class="seatreg-flower-container" style="--flower-size: 10px; --flower-delay: 4s; --flower-opacity: 0.1; top:320px; left:40px">
    41     <div class="seatreg-flower-droplet seatreg-flower-droplet-1"></div>
    42     <div class="seatreg-flower-droplet seatreg-flower-droplet-2"></div>
    43     <div class="seatreg-flower-droplet seatreg-flower-droplet-3"></div>
    44     <div class="seatreg-flower-droplet seatreg-flower-droplet-4"></div>
    45     <div class="seatreg-flower-droplet seatreg-flower-droplet-5"></div>
    46     <div class="seatreg-flower-droplet seatreg-flower-droplet-6"></div>
    47     <div class="seatreg-flower-droplet seatreg-flower-droplet-7"></div>
    48     <div class="seatreg-flower-droplet seatreg-flower-droplet-8"></div>
    49     <div class="seatreg-flower-droplet seatreg-flower-droplet-9"></div>
    50     <div class="seatreg-flower-droplet seatreg-flower-droplet-10"></div>
    51 </div>
  • seatreg/trunk/php/views/parts/registration-card.php

    r3680221 r3693621  
    118118                seatreg_more_items_modal( $seatregCode );
    119119                seatreg_copy_registration_modal( $seatregCode );
    120                 seatreg_shortcode_modal( $seatregCode, $seatregRooms );
     120                seatreg_shortcode_modal( $seatregCode, $seatregRooms, SeatregTerminologyService::getRoomNouns($seatregRegistration) );
    121121        ?>
    122122</div>
  • seatreg/trunk/php/views/sections/builder_content.php

    r3496616 r3693621  
    11<?php
    22        if ( ! defined( 'ABSPATH' ) ) {
    3                 exit();
    4         }       
     3                exit();
     4        }
     5
    56?>
    67
    … …  
    910                <h1 class="reg-title"><?php esc_html_e('Registration name', 'seatreg'); ?>: <span class="reg-title-name"></span></h1>
    1011                <h2 class="room-title">
    11                         <?php esc_html_e('Room', 'seatreg'); ?>:
     12                        <?php seatreg_noun_span('room', 'singularUpper'); ?>:
    1213                        <span class="room-title-name"></span>
    1314                        <span class="change-room-name"><?php esc_html_e('Change name', 'seatreg');?></span>
    … …  
    1617                <div id="room-selection-wrapper"></div>
    1718                <div class="cre-del-room-wrapper">
    18                         <span id="new-room-create" class="room-action"><i class="fa fa-plus" aria-hidden="true"></i> <?php esc_html_e('Add room', 'seatreg');?> </span>
    19                         <span id="current-room-delete" class="room-action"><i class="fa fa-minus" aria-hidden="true"></i> <?php esc_html_e('Delete room', 'seatreg');?></span>
     19                        <span id="new-room-create" class="room-action"><i class="fa fa-plus" aria-hidden="true"></i> <?php seatreg_noun_span('room', 'singular', _x('Add %s', 'layout builder button that creates a new room', 'seatreg'));?> </span>
     20                        <span id="current-room-delete" class="room-action"><i class="fa fa-minus" aria-hidden="true"></i> <?php seatreg_noun_span('room', 'singular', _x('Delete %s', 'layout builder button that deletes the current room', 'seatreg'));?></span>
    2021                </div>
    2122        </div> <!-- end of build head-->
    … …  
    2829                                <div data-action="1" class="mouse-option action1" id="mouse-option-active" title="<?php esc_attr_e('Select, move and resize tool', 'seatreg'); ?>"></div>
    2930                                <div data-action="4" class="mouse-option action4" title="<?php esc_attr_e('Lasso select tool', 'seatreg'); ?>"></div>
    30                                 <div data-action="2" class="mouse-option action2" title="<?php esc_attr_e('Seat/place creation tool', 'seatreg'); ?>"></div>
     31                                <?php $seatregSeatToolTitle = _x('%s creation tool', 'layout builder tool that creates seats', 'seatreg'); ?>
     32                                <div data-action="2" class="mouse-option action2" title="<?php echo esc_attr( seatreg_noun_text('seat', 'singularUpper', $seatregSeatToolTitle) ); ?>"<?php echo seatreg_noun_markers('seat', 'singularUpper', $seatregSeatToolTitle, 'title'); ?>></div>
    3133                                <div data-action="5" class="mouse-option action5" title="<?php esc_attr_e('Custom box tool', 'seatreg'); ?>"></div>
    3234                                <div data-action="9" class="mouse-option action9" title="<?php esc_attr_e('Text tool', 'seatreg'); ?>"></div>
    … …  
    7577                <div class="legends"></div>
    7678                <div id="build-section-message-wrap" data-toggle="modal" data-target="#limit-dialog">
    77                         <span class="message-text"><span style="vertical-align:middle"><?php esc_html_e('Pending and booked seats can\'t be deleted', 'seatreg');?></span><span class="more-message-btn"></span></span>
     79                        <span class="message-text"><span style="vertical-align:middle"><?php seatreg_noun_span('seat', 'plural', __('Pending and booked %s can\'t be deleted', 'seatreg'));?></span><span class="more-message-btn"></span></span>
    7880                </div>
    7981                <div class="update-wrapper">
    … …  
    173175                <div class="modal-content">
    174176                        <div class="modal-header">
    175                                 <h4 class="modal-title" id="myModalLabel"><?php esc_html_e('Seat/place pricing', 'seatreg');?></h4>
     177                                <h4 class="modal-title" id="myModalLabel"><?php seatreg_noun_span('seat', 'singularUpper', _x('%s pricing', 'layout builder dialog title for setting seat prices', 'seatreg'));?></h4>
    176178                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    177179                        </div>
    … …  
    181183                                </div>
    182184                                <div class="set-price-wrap">
    183                                         <div><label for="price-for-all-selected"><?php esc_html_e('Fill price to all selected seats', 'seatreg'); ?></label></div>
     185                                        <div><label for="price-for-all-selected"><?php seatreg_noun_span('seat', 'plural', __('Fill price to all selected %s', 'seatreg')); ?></label></div>
    184186                                        <input type="number" min="0" oninput="this.value = Math.abs(this.value)" id="price-for-all-selected" value="0" />
    185187                                        <button type="button" class="btn btn-success btn-sm" id="fill-price-for-all-selected"><?php esc_html_e('Fill prices', 'seatreg'); ?></button>
    … …  
    199201                <div class="modal-content">
    200202                        <div class="modal-header">
    201                                 <h4 class="modal-title" id="myModalLabel"><?php esc_html_e('Lock seats/places', 'seatreg');?></h4>
     203                                <h4 class="modal-title" id="myModalLabel"><?php seatreg_noun_span('seat', 'pluralUpper', _x('Lock %s', 'layout builder dialog title for locking seats', 'seatreg'));?></h4>
    202204                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    203205                        </div>
    204206                        <div class="modal-body">
    205207                                <div class="set-password-wrap">
    206                                         <div><label for="password-for-all-selected"><?php esc_html_e('Fill password to all selected seats', 'seatreg'); ?></label></div>
     208                                        <div><label for="password-for-all-selected"><?php seatreg_noun_span('seat', 'plural', __('Fill password to all selected %s', 'seatreg')); ?></label></div>
    207209                                        <input type="text" id="password-for-all-selected" />
    208210                                        <button type="button" class="btn btn-success btn-sm" id="fill-password-for-all-selected"><?php esc_html_e('Fill password', 'seatreg'); ?></button>
    … …  
    222224                <div class="modal-content">
    223225                        <div class="modal-header">
    224                                 <h4 class="modal-title" id="myModalLabel"><?php esc_html_e('Seat/place numbering', 'seatreg');?></h4>
     226                                <h4 class="modal-title" id="myModalLabel"><?php seatreg_noun_span('seat', 'singularUpper', _x('%s numbering', 'layout builder dialog title for changing seat numbers', 'seatreg'));?></h4>
    225227                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    226228                        </div>
    227229                        <div class="modal-body">
    228                                 <div class="alert alert-primary d-none" id="seat-nr-change-no-selection"><?php esc_html_e('No seats/places selected', 'seatreg'); ?></div>
    229                                 <div class="alert alert-primary d-none" id="seat-nr-change-warning"><?php esc_html_e('Pending or booked seat numbers can\'t be changed', 'seatreg'); ?></div>
     230                                <div class="alert alert-primary d-none" id="seat-nr-change-no-selection"><?php seatreg_noun_span('seat', 'plural', _x('No %s selected', 'layout builder seat numbering dialog, nothing is selected', 'seatreg')); ?></div>
     231                                <div class="alert alert-primary d-none" id="seat-nr-change-warning"><?php seatreg_noun_span('seat', 'singular', __('Pending or booked %s numbers can\'t be changed', 'seatreg')); ?></div>
    230232                                <div id="seat-numbering-wrap">
    231233                                        <div>
    232                                                 <div><label for="seat-prefix"><?php esc_html_e('Seat prefix for selected seats', 'seatreg'); ?></label></div>
     234                                                <div><label for="seat-prefix"><?php seatreg_noun_span('seat', 'singularUpper', _x('%s prefix for the selected ones', 'layout builder seat numbering field label', 'seatreg')); ?></label></div>
    233235                                                <input type="text" id="seat-prefix" style="width:60px" />
    234236                                                <button type="button" class="btn btn-success btn-sm" id="set-seat-prefix"><?php esc_html_e('Set prefix', 'seatreg'); ?></button>
    235237                                        </div><br>
    236238                                        <div>
    237                                                 <div><label for="seat-reorder"><?php esc_html_e('Reorder selected seats starting from', 'seatreg'); ?></label></div>
     239                                                <div><label for="seat-reorder"><?php seatreg_noun_span('seat', 'plural', __('Reorder selected %s starting from', 'seatreg')); ?></label></div>
    238240                                                <input type="number" id="seat-reorder" size="3" style="width:60px" />
    239                                                 <button type="button" class="btn btn-success btn-sm" id="reorder-seats"><?php esc_html_e('Reorder seats', 'seatreg'); ?></button>
     241                                                <button type="button" class="btn btn-success btn-sm" id="reorder-seats"><?php seatreg_noun_span('seat', 'pluralUpper', _x('Reorder %s', 'layout builder button that renumbers the selected seats', 'seatreg')); ?></button>
    240242                                        </div>
    241243                                </div>
    … …  
    268270
    269271                                <div class="legend-dialog-div">
    270                                         <label for="legend-delete-select-room" class="legend-dialog-label"><?php esc_html_e('Remove legend from this room:', 'seatreg');?></label>
     272                                        <label for="legend-delete-select-room" class="legend-dialog-label"><?php
     273                                                /* translators: %s: the word the admin uses for a room */
     274                                                seatreg_noun_span('room', 'singular', __('Remove legend from this %s:', 'seatreg'));
     275                                        ?></label>
    271276                                        <select class="legend-select-room" id="legend-delete-select-room"></select>
    272277                                        <button type="button" id="delete-legend-from-room" class="btn btn-secondary d-block btn-sm"><?php esc_html_e('Remove', 'seatreg');?></button>
    … …  
    373378                        <div class="modal-content">
    374379                                <div class="modal-header">
    375                                         <h4 class="modal-title" id="myModalLabel"><?php esc_html_e('Room name', 'seatreg');?></h4>
     380                                        <h4 class="modal-title" id="myModalLabel"><?php seatreg_noun_span('room', 'singularUpper', _x('%s name', 'layout builder dialog title for naming a room', 'seatreg'));?></h4>
    376381                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    377382                                </div>
    378383                                <div class="modal-body">
    379                                         <label for="room-name-dialog-input"><?php esc_html_e('Enter room name:', 'seatreg');?> </label>
     384                                        <label for="room-name-dialog-input"><?php seatreg_noun_span('room', 'singular', _x('Enter %s name:', 'layout builder room name field label', 'seatreg'));?> </label>
    380385                                        <input type="text" id="room-name-dialog-input">
    381386                                        <div class="room-name-error"></div>
    … …  
    393398                        <div class="modal-content">
    394399                                <div class="modal-header">
    395                                         <h4 class="modal-title"><?php esc_html_e('Room description', 'seatreg');?></h4>
     400                                        <h4 class="modal-title"><?php seatreg_noun_span('room', 'singularUpper', _x('%s description', 'layout builder dialog title for a room description', 'seatreg'));?></h4>
    396401                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    397402                                </div>
    398403                                <div class="modal-body">
    399404                                        <p><?php esc_html_e('Will be displayed on the registration view.', 'seatreg'); ?></p>
    400                                         <label for="room-description-input"><?php esc_html_e('Enter room description:', 'seatreg');?> </label><br>
     405                                        <label for="room-description-input"><?php seatreg_noun_span('room', 'singular', _x('Enter %s description:', 'layout builder room description field label', 'seatreg'));?> </label><br>
    401406                                        <textarea id="room-description-input" cols="50"></textarea>
    402407                                        <div class="room-description-error"></div>
    … …  
    436441                                                <div class="guide-item2 guide-item-add"></div>
    437442                                                <p class="help-dialog-text">
    438                                                         <?php esc_html_e('With this tool you can create seats/places. Simply click on gray dotted box and new seat/place will be created. You can create multiple seats/places at once by dragging cursor over gray boxes.', 'seatreg');?>
     443                                                        <?php seatreg_noun_span('seat', 'plural,singular,plural', __('With this tool you can create %1$s. Simply click on gray dotted box and new %2$s will be created. You can create multiple %3$s at once by dragging cursor over gray boxes.', 'seatreg'));?>
    439444                                                </p>
    440445                                        </div>
    … …  
    499504                                                <div class="guide-item2 guide-item-price"></div>
    500505                                                <p class="help-dialog-text">
    501                                                         <?php esc_html_e('Lets you add prices to seats/places. You also need to configure paypal in settings to enable payments.', 'seatreg');?>
     506                                                        <?php seatreg_noun_span('seat', 'plural', __('Lets you add prices to %s. You also need to configure paypal in settings to enable payments.', 'seatreg'));?>
    502507                                                </p>
    503508                                        </div>
    … …  
    506511                                                <div class="guide-item2 guide-item-lock"></div>
    507512                                                <p class="help-dialog-text">
    508                                                         <?php esc_html_e('Lets you lock or set password to seats/places. When seat/place is locked then only admin can book it using booking-manager. If password is added then it is required before booking can be made.', 'seatreg');?>
     513                                                        <?php seatreg_noun_span('seat', 'plural,singular', __('Lets you lock or set password to %1$s. When a %2$s is locked then only admin can book it using booking-manager. If password is added then it is required before booking can be made.', 'seatreg'));?>
    509514                                                </p>
    510515                                        </div>
    … …  
    513518                                                <div class="guide-item2 guide-item-seat-nr"></div>
    514519                                                <p class="help-dialog-text">
    515                                                         <?php esc_html_e('Lets you change seat/place numbers. Pending and booked seat/place numbers can\'t be changed.', 'seatreg');?>
     520                                                        <?php seatreg_noun_span('seat', 'singular,singular', __('Lets you change %1$s numbers. Pending and booked %2$s numbers can\'t be changed.', 'seatreg'));?>
    516521                                                </p>
    517522                                        </div>
    … …  
    566571                        <div class="modal-content">
    567572                                <div class="modal-header">
    568                                         <h4 class="modal-title"><?php esc_html_e('Room background image', 'seatreg');?></h4>
     573                                        <h4 class="modal-title"><?php
     574                                                /* translators: %s: the word the admin uses for a room, capitalized */
     575                                                seatreg_noun_span('room', 'singularUpper', __('%s background image', 'seatreg'));
     576                                        ?></h4>
    569577                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    570578                                </div>
    571579                                <div class="modal-body">
    572                                         <h4><?php esc_html_e('Current room image', 'seatreg');?></h4>
     580                                        <h4><?php
     581                                                /* translators: %s: the word the admin uses for a room */
     582                                                seatreg_noun_span('room', 'singular', __('Current %s image', 'seatreg'));
     583                                        ?></h4>
    573584                                        <div id="activ-room-img-wrap"></div>
    574585                                        <br>
  • seatreg/trunk/readme.txt

    r3680221 r3693621  
    44Requires at least: 5.3
    55Requires PHP: 7.2.28
    6 Tested up to: 7.0
    7 Stable tag: 1.76.0
     6Tested up to: 7.1
     7Stable tag: 1.77.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
    … …  
    5050== Changelog ==
    5151
     52= 1.77.0 =
     53* The Overview page has been redesigned.
     54* You can now rename "room" to any word that fits your registration, such as stall or hall.
     55* You can now rename "seat" to any word that fits your registration, such as booth or bed.
     56* The words you use for a room and a seat can now be translated with Polylang.
     57* A registration embedded with the shortcode now opens in the language of the page it sits on.
     58
    5259= 1.76.0 =
    5360* The Home page now shows your registrations as cards, each with its status, dates, and booking counts.
  • seatreg/trunk/registration/index.php

    r3624498 r3693621  
    2424        $registrationTimeRestoriction = SeatregTimeRepository::getTimeInfoForRegistrationView($data->registration_start_time, $data->registration_end_time);
    2525        $hasFailedTimeRestriction = !$registrationTimeRestoriction->registrationStartCheck  || !$registrationTimeRestoriction->registrationEndCheck;
    26         $usingSeats = $data->using_seats === '1';
     26        $roomNouns = SeatregTerminologyService::getRoomNouns($data);
     27        $seatNouns = SeatregTerminologyService::getSeatNouns($data);
    2728        $requireWPLogin = $data->require_wp_login === '1';
    2829        $showInfoButton = $data->show_info_button === '1';
    … …  
    4849?>
    4950<!DOCTYPE html>
    50 <html lang="en">
     51<html <?php language_attributes(); ?>>
    5152<head>
    5253        <meta charset="UTF-8">
    … …  
    130131                                                <?php if( SeatregLayoutService::getRoomsLength( SeatregLayoutService::getRoomDataFromLayout($data->registration_layout) ) > 1 ): ?>
    131132                                                        <div id="room-nav-btn">
    132                                                                 <?php esc_html_e('Change room', 'seatreg'); ?>
     133                                                                <?php
     134                                                                        /* translators: %s: the word the admin uses for a room */
     135                                                                        echo esc_html( sprintf( __('Change %s', 'seatreg'), $roomNouns->singular ) );
     136                                                                ?>
    133137                                                        </div>
    134138                                                <?php endif; ?>
    … …  
    163167                                                <div id="room-is-empty" class="dont-display">
    164168                                                        <p class="room-is-empty-text">
    165                                                                 <?php esc_html_e('Room is empty', 'seatreg'); ?>
     169                                                                <?php
     170                                                                        /* translators: %s: the word the admin uses for a room, capitalized */
     171                                                                        echo esc_html( sprintf( __('%s is empty', 'seatreg'), $roomNouns->singularUpper ) );
     172                                                                ?>
    166173                                                        </p>
    167174                                                </div> 
    … …  
    186193                                                                <div id="cart-text">
    187194                                                                        <div class="seats-in-cart">0</div>
    188                                                                         <div><?php $usingSeats ? esc_html_e('seats selected', 'seatreg') : esc_html_e('places selected', 'seatreg'); ?></div>
     195                                                                        <div><?php
     196                                                                        /* translators: %s: the word the admin uses for seats, plural */
     197                                                                        echo esc_html( sprintf( __('%s selected', 'seatreg'), $seatNouns->plural ) );
     198                                                                ?></div>
    189199                                                                </div>
    190200                                                        </div>
    … …  
    262272                                                ?>
    263273                                                <div>
    264                                                         <?php esc_html_e('Total rooms', 'seatreg'); ?>: <span class="total-rooms"></span>
     274                                                        <?php
     275                                                                /* translators: %s: the word the admin uses for rooms, plural */
     276                                                                echo esc_html( sprintf( __('Total %s', 'seatreg'), $roomNouns->plural ) );
     277                                                        ?>: <span class="total-rooms"></span>
    265278                                                </div>
    266279                                                <div>
    267                                                         <?php $usingSeats ? esc_html_e('Total open seats', 'seatreg') : esc_html_e('Total open places', 'seatreg') ; ?>: <span class="total-open"></span>
     280                                                        <?php
     281                                                                /* translators: %s: the word the admin uses for seats, plural */
     282                                                                echo esc_html( sprintf( __('Total open %s', 'seatreg'), $seatNouns->plural ) );
     283                                                        ?>: <span class="total-open"></span>
    268284                                                </div>
    269285                                                <div>
    … …  
    352368                                                        <div class="row-room">
    353369                                                                <?php
    354                                                                         esc_html_e('Room', 'seatreg');
     370                                                                        echo esc_html($roomNouns->singularUpper);
    355371                                                                ?>
    356372                                                        </div>
    … …  
    433449                                        <div class="cart-icon-text">
    434450                                                <span class="seats-in-cart">0</span>
    435                                                 <?php
    436                                                         $usingSeats ? esc_html_e('seats selected', 'seatreg') : esc_html_e('places selected', 'seatreg');
     451                                                <?php
     452                                                        /* translators: %s: the word the admin uses for seats, plural */
     453                                                        echo esc_html( sprintf( __('%s selected', 'seatreg'), $seatNouns->plural ) );
    437454                                                ?>
    438455                                        </div>
  • seatreg/trunk/registration/js/registration.js

    r3641857 r3693621  
    11(function($) {
    22        var translator = createSeatregTranslator(window.seatregTranslations);
    3 
    4         function capitalizeFirstLetter(string) {
    5             return string.charAt(0).toUpperCase() + string.slice(1);
    6         }
    73
    84        $('.time').each(function() {
    … …  
    109105                this.payPalCurrencyCode = window.payPalCurrencyCode;
    110106                this.enteredSeatPasswords = {};
    111                 this.usingSeats = usingSeats === '1';
     107
    112108                this.usingCalendar = window.usingCalendar === '1' ? true : false;
    113109                this.enabledCalendarDates = window.calendarDates ? window.calendarDates.split(',') : [];
    114                 this.spotName =  this.usingSeats ? translator.translate('seat') : translator.translate('place');
     110                this.roomNouns = seatregRoomNouns();
     111                this.seatNouns = seatregSeatNouns();
    115112                this.activeCalendarDate = window.activeCalendarDate;
    116113                this.siteLanguage = window.siteLanguage;
    … …  
    559556        var infoLoc = this.rooms[this.currentRoom].room;
    560557        var documentFragment = $(document.createDocumentFragment());
    561         var text = this.usingSeats ? translator.translate('openSeatsInRoom_') : translator.translate('openPlacesInRoom_');
    562 
    563558        documentFragment.append(
    564                 '<div class="info-item open-seats">' +
    565                 '<span>' +
    566                 text +
    567                 '</span>' +
    568                 infoLoc.roomOpenSeats +
    569                 '</div>',
    570                 '<div class="info-item"><span class="bron-legend"></span> <span>'+ translator.translate('pendingSeatInRoom_') +'</span>' + infoLoc.roomBronSeats +'</div>', '<div class="info-item"><span class="tak-legend"></span> <span>'+ translator.translate('confirmedSeatInRoom_') +'</span>' + infoLoc.roomTakenSeats +'</div>');
     559                '<div class="info-item open-seats">' +
     560                '<span>' +
     561                seatregFormat(translator.translate('openSpotsInRoom'), [this.seatNouns.plural, this.roomNouns.singular, infoLoc.roomOpenSeats]) +
     562                '</span>' +
     563                '</div>',
     564                '<div class="info-item"><span class="bron-legend"></span> <span>'+ seatregFormat(translator.translate('pendingBookingsInRoom'), [this.roomNouns.singular, infoLoc.roomBronSeats]) +'</span></div>', '<div class="info-item"><span class="tak-legend"></span> <span>'+ seatregFormat(translator.translate('approvedBookingsInRoom'), [this.roomNouns.singular, infoLoc.roomTakenSeats]) +'</span></div>');
    571565
    572566        $('#room-nav-info-inner').html(documentFragment);
    … …  
    769763
    770764                if(scope.selectedSeats.length == 0) {
    771                         $('#seat-cart-info').html('<h3>'+ translator.translate('selectionIsEmpty') +'</h3><p>' + translator.translate('youCanAdd_') + scope.spotName + translator.translate('_toCartClickTab') + '</p>');
     765                        $('#seat-cart-info').html('<h3>'+ seatregFormat(translator.translate('selectionIsEmpty'), [scope.seatNouns.singularUpper]) +'</h3><p>' + seatregFormat(translator.translate('youCanAddToSelection'), [scope.seatNouns.plural]) + '</p>');
    772766                        $('#checkout').css('display','none');
    773767                        $('#seat-cart-rows').css('display','none');
    … …  
    779773                        var infoText;
    780774
    781                         if( selected > 1 ) {
    782                                 infoText = selected + (this.usingSeats ? translator.translate('_seatsSelected') : translator.translate('_placesSelected') );
    783                         }else {
    784                                 infoText = selected + (this.usingSeats ? translator.translate('_seatSelected') : translator.translate('_placeSelected') );
    785                         }
     775                        infoText = seatregFormat(translator.translate('spotsSelected'), [selected, selected > 1 ? scope.seatNouns.plural : scope.seatNouns.singular]);
    786776                        $('#seat-cart-info').text(infoText);
    787777                        let totalPrice = scope.calculateBookingCost();
    … …  
    819809SeatReg.prototype.openSeatCart = function() {
    820810        var selected = this.selectedSeats.length;
    821         var cartHeaderText = this.usingSeats ? translator.translate('selectionIsEmpty') : translator.translate('selectionIsEmptyPlace');
    822         var cartEmptyText = this.usingSeats ? translator.translate('selectingGuide') : translator.translate('selectingGuidePlace');
     811        var cartHeaderText = seatregFormat(translator.translate('selectionIsEmpty'), [this.seatNouns.singularUpper]);
     812        var cartEmptyText = seatregFormat(translator.translate('selectingGuide'), [this.seatNouns.singular]);
    823813        this.resetCouponMarkup();
    824814
    … …  
    838828                var infoText;
    839829
    840                 if(selected > 1) {
    841                         infoText = selected + ( this.usingSeats ? translator.translate('_seatsSelected') : translator.translate('_placesSelected') );
    842                 }else {
    843                         infoText = selected + translator.translate('_seatSelected');
    844                         infoText = selected + ( this.usingSeats ? translator.translate('_seatSelected') : translator.translate('_placeSelected') );
    845                 }
     830                infoText = seatregFormat(translator.translate('spotsSelected'), [selected, selected > 1 ? this.seatNouns.plural : this.seatNouns.singular]);
    846831                $('#seat-cart-info').text(infoText);
    847832
    … …  
    11391124                if(!isSelected) {
    11401125                        if(isLocked) {
    1141                                 var text = this.usingSeats ? translator.translate('seatIsLocked') : translator.translate('placeIsLocked');
     1126                                var text = seatregFormat(translator.translate('spotIsLocked'), [this.seatNouns.singularUpper]);
    11421127
    11431128                                $('#confirm-dialog-bottom').empty();
    … …  
    11581143                                        $('#confirm-dialog-mob-text').html('<div class="seat-taken-notify">' + text + '</div>');
    11591144                                }else if( this.status == 'run' && !this.hasFailedTimeRestrictions() ) {
    1160                                         var maxPlacesText = this.usingSeats ? translator.translate('maxSeatsToAdd') : translator.translate('maxPlacesToAdd');
    1161                                        
    1162                                         $('#confirm-dialog-mob-text').html('<div class="add-seat-text"><h5>'+ translator.translate('add_') + ' ' + this.spotName + ' ' + seatPrefix + nr + translator.translate('_fromRoom_') + ' ' + room + translator.translate('_toSelection') +'</h5><p>'+ maxPlacesText + ' ' + this.seatLimit +'</p>' + '</div>');
     1145                                        var maxPlacesText = seatregFormat(translator.translate('maxSpotsToAdd'), [this.seatNouns.plural, this.seatLimit]);
     1146
     1147                                        $('#confirm-dialog-mob-text').html('<div class="add-seat-text"><h5>'+ seatregFormat(translator.translate('addSpotFromRoomToBooking'), [this.seatNouns.singular, seatPrefix + nr, this.roomNouns.singular, room]) +'</h5><p>'+ maxPlacesText +'</p>' + '</div>');
    11631148
    11641149                                        if(this.isPaymentEnabled() && this.payPalCurrencyCode && price > 0) {
    1165                                                 var placeCostText = this.usingSeats ? translator.translate('seatCosts_') : translator.translate('placeCosts_');
    1166 
    1167                                                 $('#confirm-dialog-mob-text .add-seat-text').append('<p>' + placeCostText + '<strong>' +  getCurrencySymbolFromISO(this.payPalCurrencyCode) + price + '</strong></p>');
     1150                                                var placeCostText = seatregFormat(translator.translate('spotCosts'), [this.seatNouns.singular, '<strong>' + getCurrencySymbolFromISO(this.payPalCurrencyCode) + price + '</strong>']);
     1151
     1152                                                $('#confirm-dialog-mob-text .add-seat-text').append('<p>' + placeCostText + '</p>');
    11681153                                        }
    11691154                                }else {
    1170                                         $('#confirm-dialog-mob-text').html('<div class="add-seat-text"><h5>' + this.spotName + ' ' + seatPrefix + nr + translator.translate('_fromRoom_')  + room + '</h5></div>');
     1155                                        $('#confirm-dialog-mob-text').html('<div class="add-seat-text"><h5>' + seatregFormat(translator.translate('spotFromRoom'), [this.seatNouns.singular, seatPrefix + nr, this.roomNouns.singular, room]) + '</h5></div>');
    11711156                                }
    11721157
    11731158                        }else if(type == 'tak') {
    11741159                                $('#confirm-dialog-bottom').empty();
    1175                                 $('#confirm-dialog-mob-text').html('<div class="seat-taken-notify"><h5>'+ translator.translate('this_') + this.spotName + translator.translate('_isOccupied') + '</h5></div>');
     1160                                $('#confirm-dialog-mob-text').html('<div class="seat-taken-notify"><h5>'+ seatregFormat(translator.translate('spotIsOccupied'), [this.seatNouns.singular]) + '</h5></div>');
    11761161                        }else if(type == 'bron') {
    11771162                                $('#confirm-dialog-bottom').empty();
    1178                                 $('#confirm-dialog-mob-text').html('<div class="seat-bron-notify"><h5>' + translator.translate('this_') +  ' ' + this.spotName + translator.translate('_isPendingState') +'</h5>'+ translator.translate('regOwnerNotConfirmed') +'</div>');
     1163                                $('#confirm-dialog-mob-text').html('<div class="seat-bron-notify"><h5>' + seatregFormat(translator.translate('spotIsPendingState'), [this.seatNouns.singular]) +'</h5>'+ translator.translate('regOwnerNotConfirmed') +'</div>');
    11791164                        }else if(type == 'rbox' && this.selectedSeats.length >= this.seatLimit ) {
    11801165                                $('#confirm-dialog-bottom').empty();
    … …  
    11831168                }else {
    11841169                        $('#confirm-dialog-bottom').empty();
    1185                         $('#confirm-dialog-mob-text').html('<div class="add-seat-text"><h5>' + capitalizeFirstLetter(this.spotName)  + ' ' + nr + translator.translate('_isAlreadySelected') +'</h5></div>');
     1170                        $('#confirm-dialog-mob-text').html('<div class="add-seat-text"><h5>' + seatregFormat(translator.translate('spotAlreadySelected'), [this.seatNouns.singularUpper, nr]) +'</h5></div>');
    11861171                }       
    11871172        }
  • seatreg/trunk/seatreg.php

    r3680221 r3693621  
    77        Author URI: https://github.com/SiimKirjanen
    88        Text Domain: seatreg
    9         Version: 1.76.0
     9        Version: 1.77.0
    1010        Requires at least: 5.3
    1111        Requires PHP: 7.2.28
    … …  
    7373require( 'php/services/SeatregCompanionAppService.php' );
    7474require( 'php/services/SeatregRegistrationStatusService.php' );
     75require( 'php/services/SeatregTerminologyService.php' );
     76require( 'php/services/SeatregStringTranslationService.php' );
    7577require( 'php/migrations/SeatregEncryptStripeCredentialsMigration.php' );
    7678require( 'php/migrations/SeatregBackfillStripeWebhookUrlMigration.php' );
Note: See TracChangeset for help on using the changeset viewer.