Skip to content

Commit

Permalink
feat(ui): redesigned UI (#8)
Browse files Browse the repository at this point in the history
Co-authored-by: Max <[email protected]>
Co-authored-by: Solareon <[email protected]>
  • Loading branch information
3 people authored Jul 19, 2024
1 parent a8c3e05 commit c2f7a7e
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 126 deletions.
Binary file added .github/assets/slrn_groups-dark.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/slrn_groups-light.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
# slrn_groups
![Lint](https://github.com/solareon/slrn_groups/actions/workflows/lint.yml/badge.svg)
![CI](https://github.com/solareon/slrn_groups/actions/workflows/ci.yml/badge.svg)

A group app for [lb-phone](https://lbphone.com/) the provides `qb-phone` compatible exports. This should work with most resources that expect a `qb-phone` style group.

**QBOX/QB/ESX/ND/OX supported with bridge**

![CI](https://github.com/solareon/slrn_groups/actions/workflows/ci.yml/badge.svg)
![Lint](https://github.com/solareon/slrn_groups/actions/workflows/lint.yml/badge.svg)
# Preview

Light Mode | Dark Mode
:-------------------------:|:-------------------------:
![Light mode preview image](.github/assets/slrn_groups-light.gif) | ![Dark mode preview image](.github/assets/slrn_groups-dark.gif)

## Installation

# Installation
Download the [release version](https://github.com/solareon/slrn_groups/releases) and copy to your server.

# Customizing and building from source
Download the latest commit and navigate to the ui folder
```bash copy
pnpm i
```
Then to preview the UI. You can also switch the UI path in the app registration (switch the commented lines) and then the game will display the preview running from vite.
```bash copy
pnpm start
```
Or to build for production
```bash copy
pnpm build
```

# Support
- [Discord](https://discord.gg/TZFBBHvG6E)

# Credits
- [FjamZoo](https://github.com/FjamZoo) for rewriting groups layer
- [MaxReinold](https://github.com/MaxReinold) for making a slick UI
- [RijayJH](https://github.com/RijayJH/rj_groups-for-lb_phone) for original idea
- [overextended](https://github.com/overextended) for ox_lib

Expand Down
4 changes: 2 additions & 2 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const App = () => {
return (
<AppProvider>
<div
className="size-full text-center text-text gap-4 bg-background"
className="size-full text-center text-text gap-4 bg-background h-screen p-4 px-6"
ref={appDiv}
data-theme={theme}
>
Expand All @@ -102,7 +102,7 @@ const App = () => {
</button>
)}
<div>&nbsp;</div>
<div className="text-left text-4xl font-bold mt-6 mb-2 pt-2">Groups</div>
<div className="text-left text-4xl font-extralight mt-6 mb-2 pt-2">Groups</div>
{currentPage === "GroupDashboard" && (
<GroupDashboard
setCurrentPage={setCurrentPage} fetchNui={fetchNui}
Expand Down
8 changes: 4 additions & 4 deletions ui/src/components/ConfirmationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ const ConfirmationDialog = ({ onClose, onConfirm, confirmation}) => {
return (
<div className="fixed inset-0 bg-black bg-opacity-75 flex justify-center items-center">
<div className="bg-background border border-primary rounded-lg p-6 w-11/12">
<h2 className="text-text text-xl font-semibold mb-4">
<h2 className="text-text text-xl font-normal mb-8">
{confirmation.message}
</h2>
<div className="flex justify-end space-x-4">
<button
className="px-4 py-2 bg-primary rounded hover:bg-secondary"
className="px-4 py-2 bg-primary rounded-lg transition-all shadow-sm hover:bg-secondary hover:scale-105 hover:shadow-lg w-1/2"
onClick={onClose}
>
No
</button>
<button
className="px-4 py-2 bg-primary rounded hover:bg-danger"
className="px-4 py-2 bg-primary hover:bg-danger rounded-lg transition-all shadow-sm hover:scale-105 hover:shadow-lg w-1/2"
onClick={onConfirm}
>
Yes
Expand All @@ -26,4 +26,4 @@ const ConfirmationDialog = ({ onClose, onConfirm, confirmation}) => {
);
};

export default ConfirmationDialog;
export default ConfirmationDialog
30 changes: 18 additions & 12 deletions ui/src/components/CreateGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { faXmark } from "@fortawesome/free-solid-svg-icons";

const CreateGroup: React.FC<any> = ({ onSelect, onClose }) => {
const [groupName, setGroupName] = useState("");
const [first, setFirst] = useState(true);
const [disabledReason, setDisabledReason] = useState("");
const [password, setPassword] = useState("");
const [verifyPassword, setVerifyPassword] = useState("");
Expand All @@ -18,7 +19,12 @@ const CreateGroup: React.FC<any> = ({ onSelect, onClose }) => {
} else if (password !== verifyPassword) {
reason = "Passwords do not match";
}
setDisabledReason(reason);
if(first) {
setFirst(false);
setDisabledReason('')
} else {
setDisabledReason(reason);
}
setIsSubmitDisabled(reason !== "");
}, [password, verifyPassword, groupName]);

Expand All @@ -32,13 +38,13 @@ const CreateGroup: React.FC<any> = ({ onSelect, onClose }) => {
<div className="fixed inset-0 bg-black bg-opacity-75 flex justify-center items-center">
<div
className="bg-background
border border-border-primary-light dark:border-none p-6 rounded-lg shadow-md w-11/12"
dark:border-none p-6 rounded-lg shadow-md w-11/12"
>
<div className="flex justify-between items-center mb-4">
<h2 className="text-2xl font-bold">Create Group</h2>
<h2 className="text-3xl font-light">Create Group</h2>
<FontAwesomeIcon icon={faXmark} onClick={onClose} size="2xl"/>
</div>
<form className="text-left text-xl" onSubmit={handleSubmit}>
<form className="text-left text-xl font-extralight" onSubmit={handleSubmit}>
<div className="mb-4">
<label htmlFor="groupName" className="block mb-2">
Group Name
Expand All @@ -48,7 +54,7 @@ const CreateGroup: React.FC<any> = ({ onSelect, onClose }) => {
id="groupName"
value={groupName}
onChange={(e) => setGroupName(e.target.value)}
className="w-full p-2 rounded bg-secondary border dark:border-none border-secondary"
className="w-full p-2 rounded bg-primary focus-visible:outline-none focus:scale-105 hover:scale-105 transition-all"
/>
</div>
<div className="mb-4">
Expand All @@ -60,7 +66,7 @@ const CreateGroup: React.FC<any> = ({ onSelect, onClose }) => {
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full p-2 rounded bg-secondary border dark:border-none border-secondary"
className="w-full p-2 rounded bg-primary focus-visible:outline-none focus:scale-105 hover:scale-105 transition-all"
/>
</div>
<div className="mb-4">
Expand All @@ -72,32 +78,32 @@ const CreateGroup: React.FC<any> = ({ onSelect, onClose }) => {
id="verifyPassword"
value={verifyPassword}
onChange={(e) => setVerifyPassword(e.target.value)}
className="w-full p-2 rounded bg-secondary border dark:border-none border-secondary"
className="w-full p-2 rounded bg-primary focus-visible:outline-none focus:scale-105 hover:scale-105 transition-all"
/>
</div>
<div className="flex justify-end">
<button
type="button"
onClick={onClose}
className="mr-2 px-4 py-2 rounded bg-primary hover:bg-secondary"
className="mr-2 px-4 py-2 rounded bg-primary hover:bg-primary w-1/2 hover:scale-105"
>
Cancel
</button>
<button
type="submit"
disabled={isSubmitDisabled}
className={`px-4 py-2 rounded
className={`px-4 py-2 rounded w-1/2
bg-primary
${
isSubmitDisabled
? "cursor-not-allowed"
: "hover:bg-success"
? "cursor-not-allowed brightness-50 opacity-50 hover"
: "hover:bg-success hover:scale-105"
}`}
>
Submit
</button>
</div>
<div className="mt-4 text-center text-danger">
<div className="mt-4 text-center font-semibold text-red-400">
{disabledReason ? disabledReason : String.fromCharCode(160)}
</div>
</form>
Expand Down
58 changes: 22 additions & 36 deletions ui/src/components/GroupDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,17 @@ const GroupDashboard = ({ setCurrentPage, fetchNui }) => {
<FontAwesomeIcon
icon={faList}
className="mx-1 hover:text-background"
size="xl"
size="lg"
onClick={() => setShowPlayerList(true)}
/>
{isLeader && (
<FontAwesomeIcon
icon={faTrash}
className="mx-1 hover:text-danger"
size="xl"
size="lg"
onClick={() => deleteGroup(group)}
/>
)}
{isMember && !isLeader && (
<FontAwesomeIcon
icon={faRightFromBracket}
className="mx-1 hover:text-danger"
onClick={() => leaveGroup(group)}
size="xl"
/>
)}
</div>
</>
);
Expand All @@ -82,34 +74,31 @@ const GroupDashboard = ({ setCurrentPage, fetchNui }) => {
<div className="flex items-center select-none">
<div className="w-full p-2">
<div className="mb-4 flex gap-x-2">
<button
{!inGroup?(<button
onClick={() => setShowCreateGroup(true)}
disabled={inGroup}
className={`py-2 w-1/3 text-lg bg-primary rounded
${inGroup ? "cursor-not-allowed" : "hover:bg-secondary"}`}
className={`py-12 w-full text-lg bg-primary transition-all rounded-3xl shadow-sm
${inGroup ? "cursor-not-allowed" : "hover:scale-105 hover:shadow-lg"}`}
>
Create Group
</button>
<button
</button>):''}
{inGroup?(<button
onClick={() => setCurrentPage("GroupJob")}
disabled={!inGroup}
className={`py-2 w-1/3 text-lg bg-primary rounded
${!inGroup ? "cursor-not-allowed" : "hover:bg-secondary"}`}
className={`py-6 w-1/2 text-lg bg-primary transition-all rounded-2xl shadow-sm
${!inGroup ? "cursor-not-allowed" : "hover:scale-105 hover:shadow-lg hover:bg-secondary"}`}
>
Show Tasks
</button>
<button
</button>):''}
{inGroup?(<button
onClick={() => leaveGroup()}
disabled={!inGroup}
className={`py-2 w-1/3 text-lg bg-primary rounded
${!inGroup ? "cursor-not-allowed" : "hover:bg-danger"}`}
className={`py-6 w-1/2 text-lg bg-primary transition-all rounded-2xl shadow-sm
${!inGroup ? "cursor-not-allowed" : "hover:bg-danger hover:scale-105 hover:shadow-lg"}`}
>
Leave Group
</button>
</button>):''}
</div>
<h2 className="mb-4 text-2xl">
{currentGroups?.length > 0 ? (
'Create a group or join an existing group below'
inGroup?'You are already in a group.':'Create a group or join an existing group below'
) : (
'Create a group to get started'
)}
Expand All @@ -120,10 +109,9 @@ const GroupDashboard = ({ setCurrentPage, fetchNui }) => {
let isMember = group.id === inGroup;

return (
// <div className="bg-secondary p-4 rounded-lg shadow-inner">
<div
key={index}
className={`p-4 bg-secondary rounded-md flex justify-between items-center mb-2 ${
className={`p-4 bg-primary rounded-xl flex justify-between items-center mb-2 ${
!inGroup && "hover:bg-accent"
}`}
onClick={() => {
Expand All @@ -132,21 +120,19 @@ const GroupDashboard = ({ setCurrentPage, fetchNui }) => {
}
}}
>
<div className="flex items-center">
<FontAwesomeIcon icon={faUsers} className="mr-2" size="xl"/>
<span className="text-2xl font-bold">{group.name}</span>
<div className="flex items-center text-lg">
<span>
{group.memberCount}
</span>
<FontAwesomeIcon icon={faUserGroup} className="mx-2 mr-4" size="xs"/>
<span className="border-l pl-4">{group.name}</span>
</div>
<div className="flex items-center">
<>
{isMember && renderIcons(isLeader, isMember, group)}
<FontAwesomeIcon icon={faUserGroup} size="xl"/>
<span className="mx-2 font-semibold">
{group.memberCount}
</span>
</>
</div>
</div>
// </div>
);
})}
</>
Expand Down
17 changes: 7 additions & 10 deletions ui/src/components/GroupJob.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,23 @@ const GroupJob: React.FC<GroupJobProps> = ({ setCurrentPage, fetchNui }) => {
return (
<div className="flex items-center">
<div className="w-full">
<div className="mb-4 flex gap-x-2 text-xl px-2">
<div className="mb-4 flex gap-x-2 text-lg p-2">
<button
onClick={() => setCurrentPage("GroupDashboard")}
className={`p-2 w-1/2 bg-primary rounded
${!inGroup ? "cursor-not-allowed" : "hover:bg-secondary"}`}
className={`py-6 w-1/2 bg-primary transition-all rounded-2xl shadow-sm
${!inGroup ? "cursor-not-allowed" : "hover:bg-secondary hover:scale-105 hover:shadow-lg"}`}
>
Show Groups
</button>
<button
onClick={() => leaveGroup()}
className={`px-4 py-2 w-1/2 bg-primary rounded
${!inGroup ? "cursor-not-allowed" : "hover:bg-danger"}`}
className={`p-6 w-1/2 bg-primary transition-all rounded-2xl shadow-sm
${!inGroup ? "cursor-not-allowed" : "hover:bg-danger hover:scale-105 hover:shadow-lg"}`}
>
Leave Group
</button>
</div>
<span className="mb-6 text-2xl">
<span className="mb-6 text-xl">
{groupJobSteps && groupJobSteps.length > 0
? "Here are the current group tasks"
: "No tasks available"}
Expand All @@ -81,10 +81,7 @@ const GroupJob: React.FC<GroupJobProps> = ({ setCurrentPage, fetchNui }) => {
/>
</span>
<div className="ml-8">
{/* <div className="text-sm mx-2">
{step.isDone ? "1 / 1" : "0 / 1"}
</div> */}
<div className="text-2xl">{step.name}</div>
<div className="text-lg">{step.name}</div>
</div>
</div>
))}
Expand Down
Loading

0 comments on commit c2f7a7e

Please sign in to comment.