mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-09-23 09:42:56 +00:00
Merge branch 'master' into experimentalEventStreamEmitter
This commit is contained in:
@@ -5,7 +5,7 @@ const moment = require('moment');
|
||||
import request from '../../../../utils/request-middleware.js';
|
||||
|
||||
const googleDriveIcon = require('../../../../googleDrive.svg');
|
||||
const homebreweryIcon = require('../../../../thumbnail.png');
|
||||
const homebreweryIcon = require('../../../../thumbnail.svg');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const BrewItem = ({
|
||||
@@ -30,11 +30,11 @@ const BrewItem = ({
|
||||
}
|
||||
|
||||
request.delete(`/api/${brew.googleId ?? ''}${brew.editId}`).send().end((err, res)=>{
|
||||
if (err) reportError(err); else window.location.reload();
|
||||
});
|
||||
if(err) reportError(err); else window.location.reload();
|
||||
});
|
||||
}, [brew, reportError]);
|
||||
|
||||
const updateFilter = useCallback((type, term)=> updateListFilter(type, term), [updateListFilter]);
|
||||
const updateFilter = useCallback((type, term)=>updateListFilter(type, term), [updateListFilter]);
|
||||
|
||||
const renderDeleteBrewLink = ()=>{
|
||||
if(!brew.editId) return null;
|
||||
|
||||
@@ -1,148 +1,129 @@
|
||||
|
||||
.brewItem{
|
||||
.brewItem {
|
||||
position : relative;
|
||||
box-sizing : border-box;
|
||||
display : inline-block;
|
||||
vertical-align : top;
|
||||
box-sizing : border-box;
|
||||
box-sizing : border-box;
|
||||
overflow : hidden;
|
||||
width : 48%;
|
||||
min-height : 105px;
|
||||
margin-right : 15px;
|
||||
margin-bottom : 15px;
|
||||
padding : 5px 15px 2px 6px;
|
||||
padding-right : 15px;
|
||||
border : 1px solid #c9ad6a;
|
||||
margin-right : 15px;
|
||||
margin-bottom : 15px;
|
||||
overflow : hidden;
|
||||
vertical-align : top;
|
||||
background-color : #CAB2802E;
|
||||
border : 1px solid #C9AD6A;
|
||||
border-radius : 5px;
|
||||
box-shadow : 0px 4px 5px 0px #333333;
|
||||
break-inside : avoid;
|
||||
-webkit-column-break-inside : avoid;
|
||||
page-break-inside : avoid;
|
||||
break-inside : avoid;
|
||||
box-shadow : 0px 4px 5px 0px #333;
|
||||
background-color : #cab2802e;
|
||||
.thumbnail {
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: -1;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right top;
|
||||
mask-image: linear-gradient(80deg, #0000 20%, #050 40%);
|
||||
-webkit-mask-image: linear-gradient(80deg, #0000 20%, #050 40%);
|
||||
opacity: 50%;
|
||||
.thumbnail {
|
||||
position : absolute;
|
||||
top : 0;
|
||||
right : 0;
|
||||
z-index : -1;
|
||||
width : 150px;
|
||||
height : 100%;
|
||||
background-repeat : no-repeat;
|
||||
background-position : right top;
|
||||
background-size : contain;
|
||||
opacity : 50%;
|
||||
-webkit-mask-image : linear-gradient(80deg, #00000000 20%, #005500 40%);
|
||||
mask-image : linear-gradient(80deg, #00000000 20%, #005500 40%);
|
||||
}
|
||||
.text {
|
||||
min-height : 54px;
|
||||
h4{
|
||||
h4 {
|
||||
margin-bottom : 5px;
|
||||
font-size : 2.2em;
|
||||
}
|
||||
}
|
||||
.info{
|
||||
position: initial;
|
||||
bottom: 2px;
|
||||
font-family : ScalySansRemake;
|
||||
.info {
|
||||
position : initial;
|
||||
bottom : 2px;
|
||||
font-family : "ScalySansRemake";
|
||||
font-size : 1.2em;
|
||||
&>span{
|
||||
& > span {
|
||||
margin-right : 12px;
|
||||
line-height : 1.5em;
|
||||
|
||||
a {
|
||||
color:inherit;
|
||||
}
|
||||
a { color : inherit; }
|
||||
}
|
||||
}
|
||||
.brewTags span {
|
||||
background-color: #c8ac6e3b;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
border: 1px solid #c8ac6e;
|
||||
border-radius: 4px;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
border-color: currentColor;
|
||||
cursor : pointer;
|
||||
&:before {
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-size: 12px;
|
||||
margin-right: 3px;
|
||||
display : inline-block;
|
||||
padding : 2px;
|
||||
margin : 2px;
|
||||
font-weight : bold;
|
||||
white-space : nowrap;
|
||||
cursor : pointer;
|
||||
background-color : #C8AC6E3B;
|
||||
border : 1px solid #C8AC6E;
|
||||
border-color : currentColor;
|
||||
border-radius : 4px;
|
||||
&::before {
|
||||
margin-right : 3px;
|
||||
font-family : 'Font Awesome 6 Free';
|
||||
font-size : 12px;
|
||||
}
|
||||
&.type {
|
||||
background-color: #0080003b;
|
||||
color: #008000;
|
||||
&:before{
|
||||
content: '\f0ad';
|
||||
}
|
||||
color : #008000;
|
||||
background-color : #0080003B;
|
||||
&::before { content : '\f0ad'; }
|
||||
}
|
||||
&.group {
|
||||
background-color: #5050503b;
|
||||
color: #000000;
|
||||
&:before{
|
||||
content: '\f500';
|
||||
}
|
||||
color : #000000;
|
||||
background-color : #5050503B;
|
||||
&::before { content : '\f500'; }
|
||||
}
|
||||
&.meta {
|
||||
background-color: #0000803b;
|
||||
color: #000080;
|
||||
&:before{
|
||||
content: '\f05a';
|
||||
}
|
||||
color : #000080;
|
||||
background-color : #0000803B;
|
||||
&::before { content : '\f05a'; }
|
||||
}
|
||||
&.system {
|
||||
background-color: #8000003b;
|
||||
color: #800000;
|
||||
&:before{
|
||||
content: '\f518';
|
||||
}
|
||||
color : #800000;
|
||||
background-color : #8000003B;
|
||||
&::before { content : '\f518'; }
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
.links{
|
||||
opacity : 1;
|
||||
}
|
||||
&:hover {
|
||||
.links { opacity : 1; }
|
||||
}
|
||||
&:nth-child(2n + 1){
|
||||
margin-right : 0px;
|
||||
}
|
||||
.links{
|
||||
&:nth-child(2n + 1) { margin-right : 0px; }
|
||||
.links {
|
||||
.animate(opacity);
|
||||
position : absolute;
|
||||
top : 0px;
|
||||
right : 0px;
|
||||
height : 100%;
|
||||
width : 2em;
|
||||
opacity : 0;
|
||||
background-color : fade(black, 60%);
|
||||
height : 100%;
|
||||
text-align : center;
|
||||
a{
|
||||
background-color : fade(black, 60%);
|
||||
opacity : 0;
|
||||
a {
|
||||
.animate(opacity);
|
||||
display : block;
|
||||
margin : 8px 0px;
|
||||
opacity : 0.6;
|
||||
font-size : 1.3em;
|
||||
color : white;
|
||||
text-decoration : unset;
|
||||
&:hover{
|
||||
opacity : 1;
|
||||
}
|
||||
i{
|
||||
cursor : pointer;
|
||||
}
|
||||
opacity : 0.6;
|
||||
&:hover { opacity : 1; }
|
||||
i { cursor : pointer; }
|
||||
}
|
||||
}
|
||||
.googleDriveIcon {
|
||||
height : 18px;
|
||||
padding : 0px;
|
||||
margin : -5px;
|
||||
height : 18px;
|
||||
}
|
||||
.homebreweryIcon {
|
||||
mix-blend-mode : darken;
|
||||
height : 24px;
|
||||
position : relative;
|
||||
top : 5px;
|
||||
left : -5px;
|
||||
position : relative;
|
||||
padding : 0px;
|
||||
top : 5px;
|
||||
left : -7.5px;
|
||||
height : 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
.noColumns(){
|
||||
.noColumns() {
|
||||
column-count : auto;
|
||||
column-fill : auto;
|
||||
column-gap : normal;
|
||||
@@ -13,177 +13,151 @@
|
||||
height : auto;
|
||||
min-height : 279.4mm;
|
||||
margin : 20px auto;
|
||||
contain : unset;
|
||||
contain : unset;
|
||||
}
|
||||
.listPage{
|
||||
.content{
|
||||
.listPage {
|
||||
.content {
|
||||
z-index : 1;
|
||||
.page{
|
||||
.page {
|
||||
.noColumns() !important; //Needed to override PHB Theme since this is on a lower @layer
|
||||
&::after{
|
||||
display : none;
|
||||
}
|
||||
.noBrews{
|
||||
&::after { display : none; }
|
||||
.noBrews {
|
||||
margin : 10px 0px;
|
||||
font-size : 1.3em;
|
||||
font-style : italic;
|
||||
}
|
||||
.brewCollection {
|
||||
h1:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
h1:hover { cursor : pointer; }
|
||||
.active::before, .inactive::before {
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-weight: 900;
|
||||
font-size: 0.6cm;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.active {
|
||||
color: var(--HB_Color_HeaderText);
|
||||
}
|
||||
.active::before {
|
||||
content: '\f107';
|
||||
}
|
||||
.inactive {
|
||||
color: #707070;
|
||||
}
|
||||
.inactive::before {
|
||||
content: '\f105';
|
||||
padding-right : 0.5em;
|
||||
font-family : 'Font Awesome 6 Free';
|
||||
font-size : 0.6cm;
|
||||
font-weight : 900;
|
||||
}
|
||||
.active { color : var(--HB_Color_HeaderText); }
|
||||
.active::before { content : '\f107'; }
|
||||
.inactive { color : #707070; }
|
||||
.inactive::before { content : '\f105'; }
|
||||
}
|
||||
}
|
||||
}
|
||||
.sort-container {
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
position : sticky;
|
||||
top : 0;
|
||||
left : 0;
|
||||
width : 100%;
|
||||
height : 30px;
|
||||
background-color : #555;
|
||||
border-top : 1px solid #666;
|
||||
border-bottom : 1px solid #666;
|
||||
color : white;
|
||||
text-align : center;
|
||||
z-index : 1;
|
||||
display : flex;
|
||||
justify-content : center;
|
||||
align-items : baseline;
|
||||
column-gap : 15px;
|
||||
row-gap : 5px;
|
||||
flex-wrap : wrap;
|
||||
h6{
|
||||
text-transform : uppercase;
|
||||
position : sticky;
|
||||
top : 0;
|
||||
left : 0;
|
||||
z-index : 1;
|
||||
display : flex;
|
||||
flex-wrap : wrap;
|
||||
row-gap : 5px;
|
||||
column-gap : 15px;
|
||||
align-items : baseline;
|
||||
justify-content : center;
|
||||
width : 100%;
|
||||
height : 30px;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
color : white;
|
||||
text-align : center;
|
||||
background-color : #555555;
|
||||
border-top : 1px solid #666666;
|
||||
border-bottom : 1px solid #666666;
|
||||
h6 {
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 11px;
|
||||
font-weight : bold;
|
||||
text-transform : uppercase;
|
||||
}
|
||||
.sort-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
color: #ccc;
|
||||
height: 100%;
|
||||
display : flex;
|
||||
align-items : center;
|
||||
height : 100%;
|
||||
padding : 0 8px;
|
||||
color : #CCCCCC;
|
||||
|
||||
&:hover{
|
||||
background-color : #444;
|
||||
}
|
||||
&:hover { background-color : #444444; }
|
||||
|
||||
&.active {
|
||||
font-weight: bold;
|
||||
color: #ddd;
|
||||
background-color: #333;
|
||||
font-weight : bold;
|
||||
color : #DDDDDD;
|
||||
background-color : #333333;
|
||||
|
||||
button {
|
||||
color: white;
|
||||
font-weight: 800;
|
||||
height: 100%;
|
||||
& + .sortDir {
|
||||
padding-left: 5px;
|
||||
button {
|
||||
height : 100%;
|
||||
font-weight : 800;
|
||||
color : white;
|
||||
& + .sortDir { padding-left : 5px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.filter-option {
|
||||
margin-left: 20px;
|
||||
background-color : transparent !important;
|
||||
margin-left : 20px;
|
||||
font-size : 11px;
|
||||
i{
|
||||
padding-right : 5px;
|
||||
}
|
||||
background-color : transparent !important;
|
||||
i { padding-right : 5px; }
|
||||
}
|
||||
button {
|
||||
padding : 0;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 11px;
|
||||
font-weight : normal;
|
||||
color : #CCCCCC;
|
||||
text-transform : uppercase;
|
||||
background-color : transparent;
|
||||
}
|
||||
button{
|
||||
background-color : transparent;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
text-transform : uppercase;
|
||||
font-weight : normal;
|
||||
font-size : 11px;
|
||||
color : #ccc;
|
||||
padding : 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
.tags-container {
|
||||
height : 30px;
|
||||
background-color : #555;
|
||||
border-top : 1px solid #666;
|
||||
border-bottom : 1px solid #666;
|
||||
color : white;
|
||||
display : flex;
|
||||
justify-content : center;
|
||||
align-items : center;
|
||||
column-gap : 15px;
|
||||
row-gap : 5px;
|
||||
flex-wrap : wrap;
|
||||
row-gap : 5px;
|
||||
column-gap : 15px;
|
||||
align-items : center;
|
||||
justify-content : center;
|
||||
height : 30px;
|
||||
color : white;
|
||||
background-color : #555555;
|
||||
border-top : 1px solid #666666;
|
||||
border-bottom : 1px solid #666666;
|
||||
span {
|
||||
padding : 3px;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 11px;
|
||||
font-weight : bold;
|
||||
color : #DFDFDF;
|
||||
cursor : pointer;
|
||||
border : 1px solid;
|
||||
border-radius : 3px;
|
||||
padding : 3px;
|
||||
cursor : pointer;
|
||||
color: #dfdfdf;
|
||||
&:before {
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-size: 12px;
|
||||
margin-right: 3px;
|
||||
&::before {
|
||||
margin-right : 3px;
|
||||
font-family : 'Font Awesome 6 Free';
|
||||
font-size : 12px;
|
||||
}
|
||||
&:after {
|
||||
content: '\f00d';
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-size: 12px;
|
||||
margin-left: 3px;
|
||||
&::after {
|
||||
margin-left : 3px;
|
||||
font-family : 'Font Awesome 6 Free';
|
||||
font-size : 12px;
|
||||
content : '\f00d';
|
||||
}
|
||||
&.type {
|
||||
background-color: #008000;
|
||||
border-color: #00a000;
|
||||
&:before{
|
||||
content: '\f0ad';
|
||||
}
|
||||
background-color : #008000;
|
||||
border-color : #00A000;
|
||||
&::before { content : '\f0ad'; }
|
||||
}
|
||||
&.group {
|
||||
background-color: #505050;
|
||||
border-color: #000000;
|
||||
&:before{
|
||||
content: '\f500';
|
||||
}
|
||||
background-color : #505050;
|
||||
border-color : #000000;
|
||||
&::before { content : '\f500'; }
|
||||
}
|
||||
&.meta {
|
||||
background-color: #000080;
|
||||
border-color: #0000a0;
|
||||
&:before{
|
||||
content: '\f05a';
|
||||
}
|
||||
background-color : #000080;
|
||||
border-color : #0000A0;
|
||||
&::before { content : '\f05a'; }
|
||||
}
|
||||
&.system {
|
||||
background-color: #800000;
|
||||
border-color: #a00000;
|
||||
&:before{
|
||||
content: '\f518';
|
||||
}
|
||||
background-color : #800000;
|
||||
border-color : #A00000;
|
||||
&::before { content : '\f518'; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.homebrew {
|
||||
.uiPage.sitePage {
|
||||
.content {
|
||||
width : ~"min(90vw, 1000px)";
|
||||
width : ~'min(90vw, 1000px)';
|
||||
padding : 2% 4%;
|
||||
margin-top : 25px;
|
||||
margin-right : auto;
|
||||
@@ -17,19 +17,19 @@
|
||||
border : 2px solid black;
|
||||
border-radius : 5px;
|
||||
button {
|
||||
width : 125px;
|
||||
margin-right : 5px;
|
||||
color : black;
|
||||
background-color : transparent;
|
||||
border : 1px solid black;
|
||||
border-radius : 5px;
|
||||
width : 125px;
|
||||
color : black;
|
||||
margin-right : 5px;
|
||||
&.active {
|
||||
background-color: #0007;
|
||||
color: white;
|
||||
&:before {
|
||||
content: '\f00c';
|
||||
font-family: 'FONT AWESOME 5 FREE';
|
||||
margin-right: 5px;
|
||||
color : white;
|
||||
background-color : #00000077;
|
||||
&::before {
|
||||
margin-right : 5px;
|
||||
font-family : 'Font Awesome 6 Free';
|
||||
content : '\f00c';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,14 @@ const EditPage = createClass({
|
||||
window.onbeforeunload = function(){};
|
||||
document.removeEventListener('keydown', this.handleControlKeys);
|
||||
},
|
||||
componentDidUpdate : function(){
|
||||
const hasChange = this.hasChanges();
|
||||
if(this.state.isPending != hasChange){
|
||||
this.setState({
|
||||
isPending : hasChange
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
handleControlKeys : function(e){
|
||||
if(!(e.ctrlKey || e.metaKey)) return;
|
||||
@@ -138,6 +146,17 @@ const EditPage = createClass({
|
||||
|
||||
this.setState((prevState)=>({
|
||||
brew : { ...prevState.brew, text: text },
|
||||
htmlErrors : htmlErrors,
|
||||
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||
},
|
||||
|
||||
handleSnipChange : function(snippet){
|
||||
//If there are errors, run the validator on every change to give quick feedback
|
||||
let htmlErrors = this.state.htmlErrors;
|
||||
if(htmlErrors.length) htmlErrors = Markdown.validate(snippet);
|
||||
|
||||
this.setState((prevState)=>({
|
||||
brew : { ...prevState.brew, snippets: snippet },
|
||||
isPending : true,
|
||||
htmlErrors : htmlErrors,
|
||||
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||
@@ -145,8 +164,7 @@ const EditPage = createClass({
|
||||
|
||||
handleStyleChange : function(style){
|
||||
this.setState((prevState)=>({
|
||||
brew : { ...prevState.brew, style: style },
|
||||
isPending : true
|
||||
brew : { ...prevState.brew, style: style }
|
||||
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||
},
|
||||
|
||||
@@ -158,8 +176,7 @@ const EditPage = createClass({
|
||||
brew : {
|
||||
...prevState.brew,
|
||||
...metadata
|
||||
},
|
||||
isPending : true,
|
||||
}
|
||||
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||
},
|
||||
|
||||
@@ -247,16 +264,17 @@ const EditPage = createClass({
|
||||
});
|
||||
if(!res) return;
|
||||
|
||||
this.savedBrew = res.body;
|
||||
this.savedBrew = {
|
||||
...this.state.brew,
|
||||
googleId : res.body.googleId ? res.body.googleId : null,
|
||||
editId : res.body.editId,
|
||||
shareId : res.body.shareId,
|
||||
version : res.body.version
|
||||
};
|
||||
history.replaceState(null, null, `/edit/${this.savedBrew.editId}`);
|
||||
|
||||
this.setState((prevState)=>({
|
||||
brew : { ...prevState.brew,
|
||||
googleId : this.savedBrew.googleId ? this.savedBrew.googleId : null,
|
||||
editId : this.savedBrew.editId,
|
||||
shareId : this.savedBrew.shareId,
|
||||
version : this.savedBrew.version
|
||||
},
|
||||
this.setState(()=>({
|
||||
brew : this.savedBrew,
|
||||
isPending : false,
|
||||
isSaving : false,
|
||||
unsavedTime : new Date()
|
||||
@@ -311,7 +329,14 @@ const EditPage = createClass({
|
||||
},
|
||||
|
||||
renderSaveButton : function(){
|
||||
if(this.state.autoSaveWarning && this.hasChanges()){
|
||||
|
||||
// #1 - Currently saving, show SAVING
|
||||
if(this.state.isSaving){
|
||||
return <Nav.item className='save' icon='fas fa-spinner fa-spin'>saving...</Nav.item>;
|
||||
}
|
||||
|
||||
// #2 - Unsaved changes exist, autosave is OFF and warning timer has expired, show AUTOSAVE WARNING
|
||||
if(this.state.isPending && this.state.autoSaveWarning){
|
||||
this.setAutosaveWarning();
|
||||
const elapsedTime = Math.round((new Date() - this.state.unsavedTime) / 1000 / 60);
|
||||
const text = elapsedTime == 0 ? 'Autosave is OFF.' : `Autosave is OFF, and you haven't saved for ${elapsedTime} minutes.`;
|
||||
@@ -324,18 +349,17 @@ const EditPage = createClass({
|
||||
</Nav.item>;
|
||||
}
|
||||
|
||||
if(this.state.isSaving){
|
||||
return <Nav.item className='save' icon='fas fa-spinner fa-spin'>saving...</Nav.item>;
|
||||
// #3 - Unsaved changes exist, click to save, show SAVE NOW
|
||||
// Use trySave(true) instead of save() to use debounced save function
|
||||
if(this.state.isPending){
|
||||
return <Nav.item className='save' onClick={()=>this.trySave(true)} color='blue' icon='fas fa-save'>Save Now</Nav.item>;
|
||||
}
|
||||
if(this.state.isPending && this.hasChanges()){
|
||||
return <Nav.item className='save' onClick={this.save} color='blue' icon='fas fa-save'>Save Now</Nav.item>;
|
||||
}
|
||||
if(!this.state.isPending && !this.state.isSaving && this.state.autoSave){
|
||||
// #4 - No unsaved changes, autosave is ON, show AUTO-SAVED
|
||||
if(this.state.autoSave){
|
||||
return <Nav.item className='save saved'>auto-saved.</Nav.item>;
|
||||
}
|
||||
if(!this.state.isPending && !this.state.isSaving){
|
||||
return <Nav.item className='save saved'>saved.</Nav.item>;
|
||||
}
|
||||
// DEFAULT - No unsaved changes, show SAVED
|
||||
return <Nav.item className='save saved'>saved.</Nav.item>;
|
||||
},
|
||||
|
||||
handleAutoSave : function(){
|
||||
@@ -379,7 +403,7 @@ const EditPage = createClass({
|
||||
const title = `${this.props.brew.title} ${systems}`;
|
||||
const text = `Hey guys! I've been working on this homebrew. I'd love your feedback. Check it out.
|
||||
|
||||
**[Homebrewery Link](${global.config.publicUrl}/share/${shareLink})**`;
|
||||
**[Homebrewery Link](${global.config.baseUrl}/share/${shareLink})**`;
|
||||
|
||||
return `https://www.reddit.com/r/UnearthedArcana/submit?title=${encodeURIComponent(title.toWellFormed())}&text=${encodeURIComponent(text)}`;
|
||||
},
|
||||
@@ -410,7 +434,7 @@ const EditPage = createClass({
|
||||
<Nav.item color='blue' href={`/share/${shareLink}`}>
|
||||
view
|
||||
</Nav.item>
|
||||
<Nav.item color='blue' onClick={()=>{navigator.clipboard.writeText(`${global.config.publicUrl}/share/${shareLink}`);}}>
|
||||
<Nav.item color='blue' onClick={()=>{navigator.clipboard.writeText(`${global.config.baseUrl}/share/${shareLink}`);}}>
|
||||
copy url
|
||||
</Nav.item>
|
||||
<Nav.item color='blue' href={this.getRedditLink()} newTab={true} rel='noopener noreferrer'>
|
||||
@@ -431,7 +455,7 @@ const EditPage = createClass({
|
||||
<Meta name='robots' content='noindex, nofollow' />
|
||||
{this.renderNavbar()}
|
||||
|
||||
{this.props.brew.lock && <LockNotification shareId={this.props.brew.shareId} message={this.props.brew.lock.editMessage} />}
|
||||
{this.props.brew.lock && <LockNotification shareId={this.props.brew.shareId} message={this.props.brew.lock.editMessage} reviewRequested={this.props.brew.lock.reviewRequested} />}
|
||||
<div className='content'>
|
||||
<SplitPane onDragFinish={this.handleSplitMove}>
|
||||
<Editor
|
||||
@@ -439,11 +463,12 @@ const EditPage = createClass({
|
||||
brew={this.state.brew}
|
||||
onTextChange={this.handleTextChange}
|
||||
onStyleChange={this.handleStyleChange}
|
||||
onSnipChange={this.handleSnipChange}
|
||||
onMetaChange={this.handleMetaChange}
|
||||
reportError={this.errorReported}
|
||||
renderer={this.state.brew.renderer}
|
||||
userThemes={this.props.userThemes}
|
||||
snippetBundle={this.state.themeBundle.snippets}
|
||||
themeBundle={this.state.themeBundle}
|
||||
updateBrew={this.updateBrew}
|
||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||
onViewPageChange={this.handleEditorViewPageChange}
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
@keyframes glideDown {
|
||||
0% {transform : translate(-50% + 3px, 0px);
|
||||
opacity : 0;}
|
||||
100% {transform : translate(-50% + 3px, 10px);
|
||||
opacity : 1;}
|
||||
0% {
|
||||
opacity : 0;transform : translate(-50% + 3px, 0px);}
|
||||
100% {
|
||||
opacity : 1;transform : translate(-50% + 3px, 10px);}
|
||||
}
|
||||
.editPage{
|
||||
.navItem.save{
|
||||
.editPage {
|
||||
.navItem.save {
|
||||
position : relative;
|
||||
width : 106px;
|
||||
text-align : center;
|
||||
position : relative;
|
||||
&.saved{
|
||||
&.saved {
|
||||
color : #666666;
|
||||
cursor : initial;
|
||||
color : #666;
|
||||
}
|
||||
}
|
||||
.googleDriveStorage {
|
||||
position : relative;
|
||||
}
|
||||
.googleDriveStorage img{
|
||||
height : 18px;
|
||||
.googleDriveStorage { position : relative; }
|
||||
.googleDriveStorage img {
|
||||
height : 18px;
|
||||
padding : 0px;
|
||||
margin : -5px;
|
||||
|
||||
&.inactive {
|
||||
filter: grayscale(1);
|
||||
}
|
||||
&.inactive { filter : grayscale(1); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
require('./lockNotification.less');
|
||||
const React = require('react');
|
||||
import './lockNotification.less';
|
||||
import * as React from 'react';
|
||||
import request from '../../../utils/request-middleware.js';
|
||||
import Dialog from '../../../../components/dialog.jsx';
|
||||
|
||||
function LockNotification(props) {
|
||||
props = {
|
||||
shareId : 0,
|
||||
disableLock : ()=>{},
|
||||
message : '',
|
||||
shareId : 0,
|
||||
disableLock : ()=>{},
|
||||
lock : {},
|
||||
message : 'Unable to retrieve Lock Message',
|
||||
reviewRequested : false,
|
||||
...props
|
||||
};
|
||||
|
||||
const removeLock = ()=>{
|
||||
alert(`Not yet implemented - ID ${props.shareId}`);
|
||||
const [reviewState, setReviewState] = React.useState(props.reviewRequested);
|
||||
|
||||
const removeLock = async ()=>{
|
||||
await request.put(`/api/lock/review/request/${props.shareId}`)
|
||||
.then(()=>{
|
||||
setReviewState(true);
|
||||
});
|
||||
};
|
||||
|
||||
const renderReviewButton = function(){
|
||||
if(reviewState){ return <button className='inactive'>REVIEW REQUESTED</button>; };
|
||||
return <button onClick={removeLock}>REQUEST LOCK REMOVAL</button>;
|
||||
};
|
||||
|
||||
return <Dialog className='lockNotification' blocking closeText='CONTINUE TO EDITOR' >
|
||||
@@ -19,11 +32,11 @@ function LockNotification(props) {
|
||||
<p>This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.</p>
|
||||
<hr />
|
||||
<h3>LOCK REASON</h3>
|
||||
<p>{props.message || 'Unable to retrieve Lock Message'}</p>
|
||||
<p>{props.message}</p>
|
||||
<hr />
|
||||
<p>Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.</p>
|
||||
<p>Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.</p>
|
||||
<button onClick={removeLock}>REQUEST LOCK REMOVAL</button>
|
||||
{renderReviewButton()}
|
||||
</Dialog>;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
&::backdrop { background-color : #000000AA; }
|
||||
|
||||
button {
|
||||
padding : 2px 15px;
|
||||
margin : 10px;
|
||||
color : white;
|
||||
background-color : #333333;
|
||||
|
||||
&.inactive,
|
||||
&:hover { background-color : #777777; }
|
||||
}
|
||||
|
||||
|
||||
@@ -168,6 +168,14 @@ const errorIndex = (props)=>{
|
||||
|
||||
**Brew ID:** ${props.brew.brewId}`,
|
||||
|
||||
// Theme Not Valid
|
||||
'10' : dedent`
|
||||
## The selected theme is not tagged as a theme.
|
||||
|
||||
The brew selected as a theme exists, but has not been marked for use as a theme with the \`theme:meta\` tag.
|
||||
|
||||
If the selected brew is your document, you may designate it as a theme by adding the \`theme:meta\` tag.`,
|
||||
|
||||
//account page when account is not defined
|
||||
'50' : dedent`
|
||||
## You are not signed in
|
||||
@@ -186,13 +194,47 @@ const errorIndex = (props)=>{
|
||||
|
||||
**Brew ID:** ${props.brew.brewId}
|
||||
|
||||
**Brew Title:** ${escape(props.brew.brewTitle)}`,
|
||||
**Brew Title:** ${escape(props.brew.brewTitle)}
|
||||
|
||||
**Brew Authors:** ${props.brew.authors?.map((author)=>{return `[${author}](/user/${author})`;}).join(', ') || 'Unable to list authors'}`,
|
||||
|
||||
// ####### Admin page error #######
|
||||
'52' : dedent`
|
||||
## Access Denied
|
||||
You need to provide correct administrator credentials to access this page.`,
|
||||
|
||||
// ####### Lock Errors
|
||||
|
||||
'60' : dedent`Lock Error: General`,
|
||||
|
||||
'61' : dedent`Lock Get Error: Unable to get lock count`,
|
||||
|
||||
'62' : dedent`Lock Set Error: Cannot lock`,
|
||||
|
||||
'63' : dedent`Lock Set Error: Brew not found`,
|
||||
|
||||
'64' : dedent`Lock Set Error: Already locked`,
|
||||
|
||||
'65' : dedent`Lock Remove Error: Cannot unlock`,
|
||||
|
||||
'66' : dedent`Lock Remove Error: Brew not found`,
|
||||
|
||||
'67' : dedent`Lock Remove Error: Not locked`,
|
||||
|
||||
'68' : dedent`Lock Get Review Error: Cannot get review requests`,
|
||||
|
||||
'69' : dedent`Lock Set Review Error: Cannot set review request`,
|
||||
|
||||
'70' : dedent`Lock Set Review Error: Brew not found`,
|
||||
|
||||
'71' : dedent`Lock Set Review Error: Review already requested`,
|
||||
|
||||
'72' : dedent`Lock Remove Review Error: Cannot clear review request`,
|
||||
|
||||
'73' : dedent`Lock Remove Review Error: Brew not found`,
|
||||
|
||||
// ####### Other Errors
|
||||
|
||||
'90' : dedent` An unexpected error occurred while looking for these brews.
|
||||
Try again in a few minutes.`,
|
||||
|
||||
|
||||
@@ -100,32 +100,32 @@ const HomePage = createClass({
|
||||
return <div className='homePage sitePage'>
|
||||
<Meta name='google-site-verification' content='NwnAQSSJZzAT7N-p5MY6ydQ7Njm67dtbu73ZSyE5Fy4' />
|
||||
{this.renderNavbar()}
|
||||
<div className="content">
|
||||
<SplitPane onDragFinish={this.handleSplitMove}>
|
||||
<Editor
|
||||
ref={this.editor}
|
||||
brew={this.state.brew}
|
||||
onTextChange={this.handleTextChange}
|
||||
renderer={this.state.brew.renderer}
|
||||
showEditButtons={false}
|
||||
snippetBundle={this.state.themeBundle.snippets}
|
||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||
onViewPageChange={this.handleEditorViewPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
/>
|
||||
<BrewRenderer
|
||||
text={this.state.brew.text}
|
||||
style={this.state.brew.style}
|
||||
renderer={this.state.brew.renderer}
|
||||
onPageChange={this.handleBrewRendererPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
themeBundle={this.state.themeBundle}
|
||||
/>
|
||||
</SplitPane>
|
||||
<div className='content'>
|
||||
<SplitPane onDragFinish={this.handleSplitMove}>
|
||||
<Editor
|
||||
ref={this.editor}
|
||||
brew={this.state.brew}
|
||||
onTextChange={this.handleTextChange}
|
||||
renderer={this.state.brew.renderer}
|
||||
showEditButtons={false}
|
||||
themeBundle={this.state.themeBundle}
|
||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||
onViewPageChange={this.handleEditorViewPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
/>
|
||||
<BrewRenderer
|
||||
text={this.state.brew.text}
|
||||
style={this.state.brew.style}
|
||||
renderer={this.state.brew.renderer}
|
||||
onPageChange={this.handleBrewRendererPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
themeBundle={this.state.themeBundle}
|
||||
/>
|
||||
</SplitPane>
|
||||
</div>
|
||||
<div className={cx('floatingSaveButton', { show: this.state.welcomeText != this.state.brew.text })} onClick={this.handleSave}>
|
||||
Save current <i className='fas fa-save' />
|
||||
|
||||
@@ -1,50 +1,40 @@
|
||||
.homePage{
|
||||
.homePage {
|
||||
position : relative;
|
||||
a.floatingNewButton{
|
||||
a.floatingNewButton {
|
||||
.animate(background-color);
|
||||
position : absolute;
|
||||
display : block;
|
||||
right : 70px;
|
||||
bottom : 50px;
|
||||
z-index : 100;
|
||||
z-index : 5001;
|
||||
display : block;
|
||||
padding : 1em;
|
||||
background-color : @orange;
|
||||
font-size : 1.5em;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
background-color : @orange;
|
||||
box-shadow : 3px 3px 15px black;
|
||||
&:hover{
|
||||
background-color : darken(@orange, 20%);
|
||||
}
|
||||
&:hover { background-color : darken(@orange, 20%); }
|
||||
}
|
||||
.floatingSaveButton{
|
||||
.floatingSaveButton {
|
||||
.animateAll();
|
||||
position : absolute;
|
||||
display : block;
|
||||
right : 200px;
|
||||
bottom : 70px;
|
||||
z-index : 100;
|
||||
z-index : 5000;
|
||||
display : block;
|
||||
padding : 0.8em;
|
||||
cursor : pointer;
|
||||
background-color : @blue;
|
||||
font-size : 0.8em;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
cursor : pointer;
|
||||
background-color : @blue;
|
||||
box-shadow : 3px 3px 15px black;
|
||||
&:hover{
|
||||
background-color : darken(@blue, 20%);
|
||||
}
|
||||
&.show{
|
||||
right : 350px;
|
||||
}
|
||||
&:hover { background-color : darken(@blue, 20%); }
|
||||
&.show { right : 350px; }
|
||||
}
|
||||
|
||||
.navItem.save{
|
||||
background-color: @orange;
|
||||
&:hover{
|
||||
background-color: @green;
|
||||
}
|
||||
.navItem.save {
|
||||
background-color : @orange;
|
||||
&:hover { background-color : @green; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,18 @@ const NewPage = createClass({
|
||||
localStorage.setItem(STYLEKEY, style);
|
||||
},
|
||||
|
||||
handleSnipChange : function(snippet){
|
||||
//If there are errors, run the validator on every change to give quick feedback
|
||||
let htmlErrors = this.state.htmlErrors;
|
||||
if(htmlErrors.length) htmlErrors = Markdown.validate(snippet);
|
||||
|
||||
this.setState((prevState)=>({
|
||||
brew : { ...prevState.brew, snippets: snippet },
|
||||
isPending : true,
|
||||
htmlErrors : htmlErrors,
|
||||
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||
},
|
||||
|
||||
handleMetaChange : function(metadata, field=undefined){
|
||||
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
|
||||
fetchThemeBundle(this, metadata.renderer, metadata.theme);
|
||||
@@ -223,38 +235,39 @@ const NewPage = createClass({
|
||||
render : function(){
|
||||
return <div className='newPage sitePage'>
|
||||
{this.renderNavbar()}
|
||||
<div className="content">
|
||||
<SplitPane onDragFinish={this.handleSplitMove}>
|
||||
<Editor
|
||||
ref={this.editor}
|
||||
brew={this.state.brew}
|
||||
onTextChange={this.handleTextChange}
|
||||
onStyleChange={this.handleStyleChange}
|
||||
onMetaChange={this.handleMetaChange}
|
||||
renderer={this.state.brew.renderer}
|
||||
userThemes={this.props.userThemes}
|
||||
snippetBundle={this.state.themeBundle.snippets}
|
||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||
onViewPageChange={this.handleEditorViewPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
/>
|
||||
<BrewRenderer
|
||||
text={this.state.brew.text}
|
||||
style={this.state.brew.style}
|
||||
renderer={this.state.brew.renderer}
|
||||
theme={this.state.brew.theme}
|
||||
themeBundle={this.state.themeBundle}
|
||||
errors={this.state.htmlErrors}
|
||||
lang={this.state.brew.lang}
|
||||
onPageChange={this.handleBrewRendererPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
allowPrint={true}
|
||||
/>
|
||||
</SplitPane>
|
||||
<div className='content'>
|
||||
<SplitPane onDragFinish={this.handleSplitMove}>
|
||||
<Editor
|
||||
ref={this.editor}
|
||||
brew={this.state.brew}
|
||||
onTextChange={this.handleTextChange}
|
||||
onStyleChange={this.handleStyleChange}
|
||||
onMetaChange={this.handleMetaChange}
|
||||
onSnipChange={this.handleSnipChange}
|
||||
renderer={this.state.brew.renderer}
|
||||
userThemes={this.props.userThemes}
|
||||
themeBundle={this.state.themeBundle}
|
||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||
onViewPageChange={this.handleEditorViewPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
/>
|
||||
<BrewRenderer
|
||||
text={this.state.brew.text}
|
||||
style={this.state.brew.style}
|
||||
renderer={this.state.brew.renderer}
|
||||
theme={this.state.brew.theme}
|
||||
themeBundle={this.state.themeBundle}
|
||||
errors={this.state.htmlErrors}
|
||||
lang={this.state.brew.lang}
|
||||
onPageChange={this.handleBrewRendererPageChange}
|
||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
|
||||
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
|
||||
allowPrint={true}
|
||||
/>
|
||||
</SplitPane>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
.newPage{
|
||||
.navItem.save{
|
||||
background-color: @orange;
|
||||
&:hover{
|
||||
background-color: @green;
|
||||
}
|
||||
.newPage {
|
||||
.navItem.save {
|
||||
background-color : @orange;
|
||||
&:hover { background-color : @green; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
.sharePage{
|
||||
.sharePage {
|
||||
nav .navSection.titleSection {
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
}
|
||||
.content{
|
||||
overflow-y : hidden;
|
||||
flex-grow : 1;
|
||||
justify-content : center;
|
||||
}
|
||||
.content { overflow-y : hidden; }
|
||||
}
|
||||
|
||||
@@ -99,14 +99,14 @@ const VaultPage = (props)=>{
|
||||
setSearching(true);
|
||||
setError(null);
|
||||
|
||||
const title = titleRef.current.value || '';
|
||||
const author = authorRef.current.value || '';
|
||||
const count = countRef.current.value || 10;
|
||||
const v3 = v3Ref.current.checked != false;
|
||||
const legacy = legacyRef.current.checked != false;
|
||||
const title = titleRef.current.value || '';
|
||||
const author = authorRef.current.value || '';
|
||||
const count = countRef.current.value || 10;
|
||||
const v3 = v3Ref.current.checked != false;
|
||||
const legacy = legacyRef.current.checked != false;
|
||||
const sortOption = sort || 'title';
|
||||
const dirOption = dir || 'asc';
|
||||
const pageProp = page || 1;
|
||||
const dirOption = dir || 'asc';
|
||||
const pageProp = page || 1;
|
||||
|
||||
setSort(sortOption);
|
||||
setdir(dirOption);
|
||||
@@ -247,7 +247,7 @@ const VaultPage = (props)=>{
|
||||
</li>
|
||||
<li>
|
||||
Some common words like "a", "after", "through", "itself", "here", etc.,
|
||||
are ignored in searches. The full list can be found
|
||||
are ignored in searches. The full list can be found
|
||||
<a href='https://github.com/mongodb/mongo/blob/0e3b3ca8480ddddf5d0105d11a94bd4698335312/src/mongo/db/fts/stop_words_english.txt'>
|
||||
here
|
||||
</a>
|
||||
@@ -286,9 +286,9 @@ const VaultPage = (props)=>{
|
||||
};
|
||||
|
||||
const renderPaginationControls = ()=>{
|
||||
if(!totalBrews) return null;
|
||||
if(!totalBrews || totalBrews < 10) return null;
|
||||
|
||||
const countInt = parseInt(props.query.count || 20);
|
||||
const countInt = parseInt(brewCollection.length || 20);
|
||||
const totalPages = Math.ceil(totalBrews / countInt);
|
||||
|
||||
let startPage, endPage;
|
||||
@@ -355,7 +355,7 @@ const VaultPage = (props)=>{
|
||||
};
|
||||
|
||||
const renderFoundBrews = ()=>{
|
||||
if(searching) {
|
||||
if(searching && !brewCollection) {
|
||||
return (
|
||||
<div className='foundBrews searching'>
|
||||
<h3 className='searchAnim'>Searching</h3>
|
||||
@@ -395,6 +395,7 @@ const VaultPage = (props)=>{
|
||||
{`Brews found: `}
|
||||
<span>{totalBrews}</span>
|
||||
</span>
|
||||
{brewCollection.length > 10 && renderPaginationControls()}
|
||||
{brewCollection.map((brew, index)=>{
|
||||
return (
|
||||
<BrewItem
|
||||
@@ -415,14 +416,14 @@ const VaultPage = (props)=>{
|
||||
<link href='/themes/V3/Blank/style.css' rel='stylesheet' />
|
||||
<link href='/themes/V3/5ePHB/style.css' rel='stylesheet' />
|
||||
{renderNavItems()}
|
||||
<div className="content">
|
||||
<SplitPane showDividerButtons={false}>
|
||||
<div className='form dataGroup'>{renderForm()}</div>
|
||||
<div className='resultsContainer dataGroup'>
|
||||
{renderSortBar()}
|
||||
{renderFoundBrews()}
|
||||
</div>
|
||||
</SplitPane>
|
||||
<div className='content'>
|
||||
<SplitPane showDividerButtons={false}>
|
||||
<div className='form dataGroup'>{renderForm()}</div>
|
||||
<div className='resultsContainer dataGroup'>
|
||||
{renderSortBar()}
|
||||
{renderFoundBrews()}
|
||||
</div>
|
||||
</SplitPane>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
*:not(input) { user-select : none; }
|
||||
|
||||
.content .dataGroup {
|
||||
:where(.content .dataGroup) {
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
background : white;
|
||||
@@ -169,9 +169,10 @@
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
max-height : 100%;
|
||||
padding : 50px 50px 70px 50px;
|
||||
padding : 70px 50px;
|
||||
overflow-y : scroll;
|
||||
background-color : #2C3E50;
|
||||
container-type : inline-size;
|
||||
|
||||
h3 { font-size : 25px; }
|
||||
|
||||
@@ -236,6 +237,7 @@
|
||||
margin-right : 40px;
|
||||
color : black;
|
||||
isolation : isolate;
|
||||
transition : width 0.5s;
|
||||
|
||||
&::after {
|
||||
position : absolute;
|
||||
@@ -269,8 +271,8 @@
|
||||
.links { z-index : 2; }
|
||||
|
||||
hr {
|
||||
margin : 0px;
|
||||
visibility : hidden;
|
||||
margin : 0px;
|
||||
}
|
||||
|
||||
.thumbnail { z-index : -1; }
|
||||
@@ -278,30 +280,37 @@
|
||||
|
||||
.paginationControls {
|
||||
position : absolute;
|
||||
top : 35px;
|
||||
left : 50%;
|
||||
display : grid;
|
||||
grid-template-areas : 'previousPage currentPage nextPage';
|
||||
grid-template-columns : 50px 1fr 50px;
|
||||
gap : 20px;
|
||||
place-items : center;
|
||||
width : auto;
|
||||
font-size : 15px;
|
||||
translate : -50%;
|
||||
|
||||
&:last-child { top : unset; }
|
||||
|
||||
.pages {
|
||||
display : flex;
|
||||
grid-area : currentPage;
|
||||
gap : 1em;
|
||||
justify-content : space-evenly;
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
padding : 5px 8px;
|
||||
text-align : center;
|
||||
|
||||
.pageNumber {
|
||||
margin-inline : 1vw;
|
||||
place-content : center;
|
||||
width : fit-content;
|
||||
min-width : 2em;
|
||||
font-family : 'Open Sans';
|
||||
font-weight : 900;
|
||||
color : white;
|
||||
text-underline-position : under;
|
||||
text-wrap : nowrap;
|
||||
text-underline-position : under;
|
||||
cursor : pointer;
|
||||
|
||||
&.currentPage {
|
||||
@@ -329,7 +338,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes trailingDots {
|
||||
@@ -344,8 +352,7 @@
|
||||
100% { content : ' ...'; }
|
||||
}
|
||||
|
||||
// media query for when the page is smaller than 1079 px in width
|
||||
@media screen and (max-width : 1079px) {
|
||||
@container (width < 670px) {
|
||||
.vaultPage {
|
||||
|
||||
.dataGroup.form .brewLookup { padding : 1px 20px 20px 10px; }
|
||||
|
||||
Reference in New Issue
Block a user