new announcements page, adding searchbar and message input.
This commit is contained in:
90
src/apps/Announcements/Announcement.js
Normal file
90
src/apps/Announcements/Announcement.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import util from "../../util"
|
||||
import server from "../../_/code/bridge/server.js"
|
||||
|
||||
css(`
|
||||
announcement- p {
|
||||
font-size: 0.85em;
|
||||
color: var(--darktext);
|
||||
}
|
||||
`)
|
||||
|
||||
class Announcement extends Shadow {
|
||||
constructor(announcement) {
|
||||
super()
|
||||
this.announcement = announcement
|
||||
}
|
||||
|
||||
render() {
|
||||
VStack(() => {
|
||||
HStack(() => {
|
||||
h3(this.announcement.message)
|
||||
.color("var(--text)")
|
||||
.fontSize(1.3, em)
|
||||
.fontWeight("normal")
|
||||
.margin(0, em)
|
||||
|
||||
// Delete button
|
||||
// if (this.announcement.creator_id === global.profile.id) {
|
||||
// img(util.cssVariable("trash-src"), "1.5em")
|
||||
// .marginRight(0.5, em)
|
||||
// .onTap(() => {
|
||||
// this.deleteAnnouncement(this.announcement)
|
||||
// })
|
||||
// }
|
||||
})
|
||||
.justifyContent("space-between")
|
||||
.verticalAlign("center")
|
||||
|
||||
p(this.announcement.author ?? "Unknown author")
|
||||
.marginTop(0.75, em)
|
||||
p(this.convertDate(this.announcement.created) ?? "No date included")
|
||||
.marginTop(0.25, em)
|
||||
})
|
||||
.paddingVertical(1.5, em)
|
||||
.paddingHorizontal(3.5, em)
|
||||
.marginHorizontal(1, em)
|
||||
.borderRadius(10, px)
|
||||
.background("var(--darkaccent)")
|
||||
.border("1px solid var(--accent)")
|
||||
.boxSizing("border-box")
|
||||
}
|
||||
|
||||
async deleteAnnouncement(announcement) {
|
||||
const result = await server.deleteAnnouncement(announcement.id, announcement.network_id, global.profile.id)
|
||||
if (result.data === null) {
|
||||
console.log("Failed to delete announcement")
|
||||
}
|
||||
}
|
||||
|
||||
convertDate(rawDate) {
|
||||
const parsed = new Date(rawDate);
|
||||
|
||||
if (isNaN(parsed.getTime())) return rawDate;
|
||||
|
||||
const month = parsed.toLocaleString("en-US", { month: "long", timeZone: "UTC" });
|
||||
const day = parsed.getUTCDate();
|
||||
const year = parsed.getUTCFullYear();
|
||||
|
||||
const hours24 = parsed.getUTCHours();
|
||||
const minutes = parsed.getUTCMinutes();
|
||||
|
||||
const hours12 = hours24 % 12 || 12;
|
||||
const ampm = hours24 >= 12 ? "PM" : "AM";
|
||||
const paddedMinutes = String(minutes).padStart(2, "0");
|
||||
|
||||
const ordinal = (n) => {
|
||||
const mod100 = n % 100;
|
||||
if (mod100 >= 11 && mod100 <= 13) return `${n}th`;
|
||||
switch (n % 10) {
|
||||
case 1: return `${n}st`;
|
||||
case 2: return `${n}nd`;
|
||||
case 3: return `${n}rd`;
|
||||
default: return `${n}th`;
|
||||
}
|
||||
};
|
||||
|
||||
return `${month} ${ordinal(day)}, ${year} at ${hours12}:${paddedMinutes} ${ampm}`;
|
||||
}
|
||||
}
|
||||
|
||||
register(Announcement)
|
||||
@@ -1,125 +1,176 @@
|
||||
import './Panel.js'
|
||||
import server from '../../_/code/bridge/serverFunctions.js'
|
||||
import './Announcement.js'
|
||||
import server from '../../_/code/bridge/server.js'
|
||||
import '../../components/SearchBar.js'
|
||||
|
||||
css(`
|
||||
announcements- {
|
||||
font-family: 'Arial';
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
announcements- h1 {
|
||||
font-family: 'Bona';
|
||||
}
|
||||
|
||||
announcements- input::placeholder {
|
||||
font-family: 'Bona Nova';
|
||||
font-size: 0.9em;
|
||||
color: var(--accent);
|
||||
announcements- .VStack::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
input::placeholder {
|
||||
font-family: Arial;
|
||||
announcements- .VStack::-webkit-scrollbar-thumb {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
appearance: none; /* remove default style */
|
||||
-webkit-appearance: none;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border: 1px solid var(--accent);
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
background-color: var(--red);
|
||||
announcements- .VStack::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
`)
|
||||
|
||||
class Announcements extends Shadow {
|
||||
announcements;
|
||||
static searchableKeys = ['message', 'author'];
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.announcements = global.currentNetwork.data.announcements.sort((a, b) => new Date(b.created) - new Date(a.created));
|
||||
console.log(this.announcements)
|
||||
}
|
||||
this.searchedAnnouncements = [];
|
||||
this.searchText = "";
|
||||
}
|
||||
|
||||
render() {
|
||||
ZStack(() => {
|
||||
|
||||
VStack(() => {
|
||||
SearchBar(this.searchText, "90vw")
|
||||
|
||||
Panel(this.announcements)
|
||||
|
||||
input("Message", "70%")
|
||||
.paddingVertical(0.75, em)
|
||||
.boxSizing("border-box")
|
||||
.paddingHorizontal(2, em)
|
||||
.color("var(--text)")
|
||||
.background("var(--searchbackground)")
|
||||
.marginBottom(1, em)
|
||||
.border("0.5px solid var(--accent)")
|
||||
.outline("none")
|
||||
.borderRadius(100, px)
|
||||
.fontFamily("Arial")
|
||||
.fontSize(1, em)
|
||||
.onKeyDown(async function(e) {
|
||||
if (e.key === "Enter") {
|
||||
const result = await server.addAnnouncement(this.value, global.currentNetwork.id, global.profile.id)
|
||||
if (result.data.status === 200) {
|
||||
window.dispatchEvent(new CustomEvent('new-announcement', {
|
||||
detail: { announcement: result.data.announcement }
|
||||
}));
|
||||
} else {
|
||||
// error
|
||||
VStack(() => {
|
||||
if (!this.announcements || this.announcements == []) {
|
||||
LoadingCircle()
|
||||
} else if (this.searchText) {
|
||||
if (this.searchedAnnouncements.length > 0) {
|
||||
for (let i = 0; i < this.searchedAnnouncements.length; i++) {
|
||||
AnnouncementCard(this.searchedAnnouncements[i])
|
||||
}
|
||||
this.value = ""
|
||||
} else {
|
||||
h2("Could not find any announcements with your search criteria.")
|
||||
.color("var(--divider)")
|
||||
.fontWeight("bold")
|
||||
.marginTop(7.5, em)
|
||||
.marginBottom(0.5, em)
|
||||
.textAlign("center")
|
||||
}
|
||||
} else if (this.announcements.length > 0) {
|
||||
for (let i = 0; i < this.announcements.length; i++) {
|
||||
AnnouncementCard(this.announcements[i])
|
||||
}
|
||||
} else {
|
||||
h2("No Announcements")
|
||||
.color("var(--divider)")
|
||||
.fontWeight("bold")
|
||||
.marginTop(7.5, em)
|
||||
.marginBottom(0.5, em)
|
||||
.textAlign("center")
|
||||
}
|
||||
})
|
||||
.overflowY("scroll")
|
||||
.gap(0.75, em)
|
||||
|
||||
if(global.currentNetwork.permissions.includes("announcements.add")) {
|
||||
HStack(() => {
|
||||
input("Image Upload", "0px", "0px")
|
||||
.attr({ name: "image-upload", type: "file" })
|
||||
.display("none")
|
||||
.visibility("hidden")
|
||||
.onChange((e) => {
|
||||
this.handleUpload(e.target.files[0]);
|
||||
})
|
||||
|
||||
div("+")
|
||||
.width(3, rem)
|
||||
.height(3, rem)
|
||||
.borderRadius(50, pct)
|
||||
.border("1px solid color-mix(in srgb, var(--accent) 60%, transparent)")
|
||||
.fontSize(2, em)
|
||||
.transform("rotate(180deg)")
|
||||
.zIndex(1001)
|
||||
.display("flex")
|
||||
.alignItems("center")
|
||||
.justifyContent("center")
|
||||
.transition("scale .2s")
|
||||
.state("touched", function (touched) {
|
||||
if(touched) {
|
||||
this.scale("1.5")
|
||||
this.color("var(--darkaccent)")
|
||||
this.backgroundColor("var(--divider)")
|
||||
} else {
|
||||
this.scale("")
|
||||
this.color("var(--divider)")
|
||||
this.backgroundColor("var(--searchbackground)")
|
||||
}
|
||||
})
|
||||
.onTouch(function (start) {
|
||||
if(start) {
|
||||
this.attr({touched: "true"})
|
||||
} else {
|
||||
this.attr({touched: ""})
|
||||
}
|
||||
})
|
||||
.onClick((done) => {
|
||||
if(done) {
|
||||
const inputSelector = this.$('[name="image-upload"]');
|
||||
inputSelector.click()
|
||||
}
|
||||
})
|
||||
|
||||
input("Add an Announcement")
|
||||
.flex("1 1 auto")
|
||||
.minWidth(0)
|
||||
.color("var(--text)")
|
||||
.background("var(--searchbackground)")
|
||||
.paddingVertical(0, rem)
|
||||
.fontSize(1, rem)
|
||||
.paddingHorizontal(1, rem)
|
||||
.borderRadius(100, px)
|
||||
.border("1px solid color-mix(in srgb, var(--accent) 60%, transparent)")
|
||||
.onTouch(function (start) {
|
||||
if (start) {
|
||||
this.style.backgroundColor = "var(--accent)"
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
|
||||
$("appmenu-").display("none")
|
||||
}, 20)
|
||||
console.log($("appmenu-"))
|
||||
this.style.backgroundColor = "var(--searchbackground)"
|
||||
}
|
||||
})
|
||||
.addEventListener("blur", () => {
|
||||
setTimeout(() => {
|
||||
$("appmenu-").display("grid")
|
||||
}, 20)
|
||||
})
|
||||
})
|
||||
.width(100, pct)
|
||||
.boxSizing("border-box")
|
||||
.position("absolute")
|
||||
.paddingHorizontal(1, rem)
|
||||
.bottom(1, vh)
|
||||
.gap(0.5, rem)
|
||||
}
|
||||
})
|
||||
.gap(1, em)
|
||||
.boxSizing("border-box")
|
||||
.width(100, pct)
|
||||
.height(100, pct)
|
||||
.horizontalAlign("center")
|
||||
.verticalAlign("end")
|
||||
.minHeight(0)
|
||||
.width(100, pct)
|
||||
.onEvent("announcementsearch", this.onAnnouncementSearch)
|
||||
.onEvent("new-announcement", this.onNewAnnouncement)
|
||||
.onEvent("deleted-announcement", this.onDeletedAnnouncement)
|
||||
.onEvent("edited-announcement", this.onEditedAnnouncement)
|
||||
})
|
||||
.backgroundColor("var(--main)")
|
||||
.boxSizing("border-box")
|
||||
.paddingVertical(1, em)
|
||||
.width(100, pct)
|
||||
.height(100, pct)
|
||||
.flex("1 1 auto")
|
||||
.onEvent("new-announcement", this.onNewAnnouncement)
|
||||
.onEvent("deleted-announcement", this.onDeletedAnnouncement)
|
||||
.onEvent("edited-announcement", this.onEditedAnnouncement)
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.getAnnouncements(global.currentNetwork.id)
|
||||
}
|
||||
|
||||
checkForUpdates(currentAnnouncements, fetchedAnnouncements) {
|
||||
if (currentAnnouncements.length !== fetchedAnnouncements.length) return true;
|
||||
|
||||
const currentMap = new Map(currentAnnouncements.map(ann => [ann.id, ann]));
|
||||
|
||||
for (const fetchedAnn of fetchedAnnouncements) {
|
||||
const currentAnn = currentMap.get(fetchedAnn.id);
|
||||
|
||||
// new event added
|
||||
if (!currentAnn) return true;
|
||||
|
||||
// existing event changed
|
||||
if (currentAnn.updated_at !== fetchedAnn.updated_at) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async getAnnouncements(networkId) {
|
||||
const fetchedAnnouncements = await server.getAnnouncements(networkId)
|
||||
if (this.checkForUpdates(this.announcements, fetchedAnnouncements.data)) {
|
||||
console.log("found updates")
|
||||
this.announcements = fetchedAnnouncements.data.sort((a, b) => new Date(b.created) - new Date(a.created));
|
||||
global.currentNetwork.data.announcements = this.announcements
|
||||
this.rerender()
|
||||
}
|
||||
addPhoto() {
|
||||
console.log("hey")
|
||||
}
|
||||
|
||||
onNewAnnouncement = (e) => {
|
||||
@@ -138,13 +189,54 @@ class Announcements extends Shadow {
|
||||
|
||||
onEditedAnnouncement = (e) => {
|
||||
let editedAnnouncement = e.detail
|
||||
const i = this.announcements.findIndex(ann => ann.id === editedPost.id)
|
||||
if (i !== -1) {
|
||||
const i = this.announcements.findIndex(ann => ann.id === editedAnnouncement.id)
|
||||
if (i !== -1) {
|
||||
this.announcements.splice(i, 1)
|
||||
this.announcements.unshift(editedAnnouncement)
|
||||
}
|
||||
this.rerender()
|
||||
}
|
||||
|
||||
onAnnouncementSearch = (e) => {
|
||||
let searchText = e.detail.searchText.toLowerCase().trim();
|
||||
if (!searchText) {
|
||||
this.searchedAnnouncements = [];
|
||||
} else {
|
||||
this.searchedAnnouncements = this.announcements.filter(announcement =>
|
||||
Announcements.searchableKeys.some(key =>
|
||||
String(announcement[key]).toLowerCase().includes(searchText)
|
||||
)
|
||||
);
|
||||
}
|
||||
this.searchText = searchText
|
||||
this.rerender()
|
||||
}
|
||||
|
||||
async getAnnouncements(networkId) {
|
||||
const fetchedAnnouncements = await server.getAnnouncements(networkId)
|
||||
if (this.checkForUpdates(this.announcements, fetchedAnnouncements.data)) {
|
||||
this.announcements = fetchedAnnouncements.data.sort((a, b) => new Date(b.created) - new Date(a.created));
|
||||
global.currentNetwork.data.announcements = this.announcements
|
||||
this.rerender()
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.getAnnouncements(global.currentNetwork.id)
|
||||
}
|
||||
|
||||
checkForUpdates(currentAnnouncements, fetchedAnnouncements) {
|
||||
if (currentAnnouncements.length !== fetchedAnnouncements.length) return true;
|
||||
|
||||
const currentMap = new Map(currentAnnouncements.map(ann => [ann.id, ann]));
|
||||
|
||||
for (const fetchedAnn of fetchedAnnouncements) {
|
||||
const currentAnn = currentMap.get(fetchedAnn.id);
|
||||
if (!currentAnn) return true;
|
||||
if (currentAnn.updated_at !== fetchedAnn.updated_at) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
register(Announcements)
|
||||
150
src/apps/Announcements/Old.js
Normal file
150
src/apps/Announcements/Old.js
Normal file
@@ -0,0 +1,150 @@
|
||||
import './Panel.js'
|
||||
import server from '../../_/code/bridge/serverFunctions.js'
|
||||
|
||||
css(`
|
||||
announcements- {
|
||||
font-family: 'Bona';
|
||||
}
|
||||
|
||||
announcements- input::placeholder {
|
||||
font-family: 'Bona Nova';
|
||||
font-size: 0.9em;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
input::placeholder {
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
appearance: none; /* remove default style */
|
||||
-webkit-appearance: none;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border: 1px solid var(--accent);
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
background-color: var(--red);
|
||||
}
|
||||
`)
|
||||
|
||||
class Announcements extends Shadow {
|
||||
announcements;
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.announcements = global.currentNetwork.data.announcements.sort((a, b) => new Date(b.created) - new Date(a.created));
|
||||
console.log(this.announcements)
|
||||
}
|
||||
|
||||
render() {
|
||||
ZStack(() => {
|
||||
VStack(() => {
|
||||
|
||||
Panel(this.announcements)
|
||||
|
||||
input("Message", "70%")
|
||||
.paddingVertical(0.75, em)
|
||||
.boxSizing("border-box")
|
||||
.paddingHorizontal(2, em)
|
||||
.color("var(--text)")
|
||||
.background("var(--searchbackground)")
|
||||
.marginBottom(1, em)
|
||||
.border("0.5px solid var(--accent)")
|
||||
.outline("none")
|
||||
.borderRadius(100, px)
|
||||
.fontFamily("Arial")
|
||||
.fontSize(1, em)
|
||||
.onKeyDown(async function(e) {
|
||||
if (e.key === "Enter") {
|
||||
const result = await server.addAnnouncement(this.value, global.currentNetwork.id, global.profile.id)
|
||||
if (result.data.status === 200) {
|
||||
window.dispatchEvent(new CustomEvent('new-announcement', {
|
||||
detail: { announcement: result.data.announcement }
|
||||
}));
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
this.value = ""
|
||||
}
|
||||
})
|
||||
})
|
||||
.gap(1, em)
|
||||
.boxSizing("border-box")
|
||||
.width(100, pct)
|
||||
.height(100, pct)
|
||||
.horizontalAlign("center")
|
||||
.verticalAlign("end")
|
||||
.minHeight(0)
|
||||
})
|
||||
.backgroundColor("var(--main)")
|
||||
.boxSizing("border-box")
|
||||
.paddingVertical(1, em)
|
||||
.width(100, pct)
|
||||
.height(100, pct)
|
||||
.flex("1 1 auto")
|
||||
.onEvent("new-announcement", this.onNewAnnouncement)
|
||||
.onEvent("deleted-announcement", this.onDeletedAnnouncement)
|
||||
.onEvent("edited-announcement", this.onEditedAnnouncement)
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.getAnnouncements(global.currentNetwork.id)
|
||||
}
|
||||
|
||||
checkForUpdates(currentAnnouncements, fetchedAnnouncements) {
|
||||
if (currentAnnouncements.length !== fetchedAnnouncements.length) return true;
|
||||
|
||||
const currentMap = new Map(currentAnnouncements.map(ann => [ann.id, ann]));
|
||||
|
||||
for (const fetchedAnn of fetchedAnnouncements) {
|
||||
const currentAnn = currentMap.get(fetchedAnn.id);
|
||||
|
||||
// new event added
|
||||
if (!currentAnn) return true;
|
||||
|
||||
// existing event changed
|
||||
if (currentAnn.updated_at !== fetchedAnn.updated_at) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async getAnnouncements(networkId) {
|
||||
const fetchedAnnouncements = await server.getAnnouncements(networkId)
|
||||
if (this.checkForUpdates(this.announcements, fetchedAnnouncements.data)) {
|
||||
console.log("found updates")
|
||||
this.announcements = fetchedAnnouncements.data.sort((a, b) => new Date(b.created) - new Date(a.created));
|
||||
global.currentNetwork.data.announcements = this.announcements
|
||||
this.rerender()
|
||||
}
|
||||
}
|
||||
|
||||
onNewAnnouncement = (e) => {
|
||||
let newAnnouncement = e.detail.announcement;
|
||||
this.announcements.push(newAnnouncement)
|
||||
this.announcements.sort((a, b) => new Date(b.created) - new Date(a.created));
|
||||
this.rerender()
|
||||
}
|
||||
|
||||
onDeletedAnnouncement = (e) => {
|
||||
let deletedId = e.detail.id
|
||||
const i = this.announcements.findIndex(ann => ann.id === deletedId)
|
||||
if (i !== -1) this.announcements.splice(i, 1);
|
||||
this.rerender()
|
||||
}
|
||||
|
||||
onEditedAnnouncement = (e) => {
|
||||
let editedAnnouncement = e.detail
|
||||
const i = this.announcements.findIndex(ann => ann.id === editedPost.id)
|
||||
if (i !== -1) {
|
||||
this.announcements.splice(i, 1)
|
||||
this.announcements.unshift(editedAnnouncement)
|
||||
}
|
||||
this.rerender()
|
||||
}
|
||||
}
|
||||
|
||||
register(Announcements)
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../../components/LoadingCircle.js"
|
||||
import server from "../../_/code/bridge/serverFunctions.js"
|
||||
import server from "../../_/code/bridge/server.js"
|
||||
|
||||
css(`
|
||||
panel- {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import util from "../../util"
|
||||
import server from "../../_/code/bridge/serverFunctions.js"
|
||||
import server from "../../_/code/bridge/server.js"
|
||||
|
||||
css(`
|
||||
eventcard- p {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import server from "../../_/code/bridge/serverFunctions"
|
||||
import server from "../../_/code/bridge/server"
|
||||
|
||||
class EventForm extends Shadow {
|
||||
inputStyles(el) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import "../../components/TopBar.js"
|
||||
import "../../components/LoadingCircle.js"
|
||||
import "./EventCard.js"
|
||||
import "./EventForm.js"
|
||||
import server from "../../_/code/bridge/serverFunctions.js"
|
||||
import server from "../../_/code/bridge/server.js"
|
||||
import "../../components/SearchBar.js"
|
||||
|
||||
css(`
|
||||
@@ -47,7 +47,10 @@ class Events extends Shadow {
|
||||
EventForm()
|
||||
|
||||
VStack(() => {
|
||||
SearchBar(this.searchText)
|
||||
HStack(() => {
|
||||
SearchBar(this.searchText, "75vw")
|
||||
AddButton()
|
||||
})
|
||||
|
||||
VStack(() => {
|
||||
if (!this.events || this.events == []) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import util from "../../util.js"
|
||||
import server from "../../_/code/bridge/serverFunctions.js"
|
||||
import server from "../../_/code/bridge/server.js"
|
||||
|
||||
css(`
|
||||
jobcard- p {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import server from "../../_/code/bridge/serverFunctions"
|
||||
import server from "../../_/code/bridge/server"
|
||||
|
||||
class JobForm extends Shadow {
|
||||
inputStyles(el) {
|
||||
|
||||
@@ -3,7 +3,8 @@ import "./JobsGrid.js"
|
||||
import "./JobCard.js"
|
||||
import "./JobForm.js"
|
||||
import "../../components/SearchBar.js"
|
||||
import server from "../../_/code/bridge/serverFunctions.js"
|
||||
import "../../components/AddButton.js"
|
||||
import server from "../../_/code/bridge/server.js"
|
||||
|
||||
css(`
|
||||
jobs- {
|
||||
@@ -47,7 +48,10 @@ class Jobs extends Shadow {
|
||||
JobForm()
|
||||
|
||||
VStack(() => {
|
||||
SearchBar(this.searchText)
|
||||
HStack(() => {
|
||||
SearchBar(this.searchText, "75vw")
|
||||
AddButton()
|
||||
})
|
||||
|
||||
VStack(() => {
|
||||
if (!this.jobs || this.jobs == []) {
|
||||
|
||||
Reference in New Issue
Block a user