Skip to content

Commit

Permalink
feat: modrintnth page(wip)
Browse files Browse the repository at this point in the history
added new compoenents, routers, and permissions to support new modrinth page
  • Loading branch information
naterfute committed Nov 25, 2024
1 parent d371979 commit 3d0f3c8
Show file tree
Hide file tree
Showing 17 changed files with 694 additions and 36 deletions.
11 changes: 11 additions & 0 deletions app/Models/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ class Permission extends Model
public const ACTION_STARTUP_SOFTWARE = 'startup.software';

public const ACTION_SETTINGS_RENAME = 'settings.rename';
public const ACTION_SETTINGS_MODRINTH = 'settings.modrinth';
public const ACTION_SETTINGS_REINSTALL = 'settings.reinstall';

public const ACTION_ACTIVITY_READ = 'activity.read';

public const ACTION_MODRINTH_DOWNLOAD = 'modrinth.download';

/**
* Should timestamps be used on this model.
*/
Expand Down Expand Up @@ -199,7 +202,9 @@ class Permission extends Model
'description' => 'Permissions that control a user\'s access to the settings for this server.',
'keys' => [
'rename' => 'Allows a user to rename this server and change the description of it.',
'modrinth' => 'Allows a user to change what loader/version of mods to download',
'reinstall' => 'Allows a user to trigger a reinstall of this server.',

],
],

Expand All @@ -209,6 +214,12 @@ class Permission extends Model
'read' => 'Allows a user to view the activity logs for the server.',
],
],
'modrinth' => [
'description' => 'Permissions that control a user\'s access to downloading mods using in app modrinth',
'keys' => [
'download' => 'Allows a user to download mods to the server using modrinth',
],
],
];

/**
Expand Down
31 changes: 31 additions & 0 deletions resources/scripts/components/elements/CheckBoxMods.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import clsx from 'clsx';
import { forwardRef } from 'react';

import styles from './styles.module.css';

type Props = Omit<React.ComponentProps<'input'>, 'type'> & {
label?: string; // Optional label text for better accessibility
inputField?: boolean; // Optional flag to display an input field
};

const CheckBox = forwardRef<HTMLInputElement, Props>(({ className, label, inputField, ...props }, ref) => (
<div className={clsx('flex items-center', className)}>
<input
ref={ref}
type='checkbox'
className={clsx(
'form-input',
styles.checkbox_input,
'accent-branding', // Use the custom branding color for the checkbox accent
{
[styles.with_input]: inputField, // Add custom styles when the input field is enabled
},
)}
{...props}
/>
{label && <label className={clsx('ml-2', styles.label)}>{label}</label>}
{inputField && <input type='text' className={clsx('ml-2', 'form-input', styles.input_field, 'border-brand')} />}
</div>
));

export default CheckBox;
42 changes: 42 additions & 0 deletions resources/scripts/components/elements/CheckboxLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from 'react';

import { cn } from '@/lib/utils';

const Checkbox = React.forwardRef<
React.ElementRef<'div'>,
React.ComponentPropsWithoutRef<'div'> & { label?: string; onChange?: () => void }
>(({ className, label, onChange, ...props }, ref) => {
const [checked, setChecked] = React.useState(false);

const toggleChecked = () => {
setChecked((prev) => {
const newCheckedState = !prev;
if (onChange) onChange(); // Call the onChange handler when the checkbox is toggled
return newCheckedState;
});
};

return (
<div className='flex items-center gap-2 select-none'>
{label && (
<span
onClick={toggleChecked}
className={cn(
'inline-block rounded-lg w-full px-2 py-1 cursor-pointer transition-colors duration-200',
checked
? 'bg-green-800 text-white mb-2 select-none'
: 'border-transparent hover:bg-gray-700 mb-2 select-none',
)}
{...props}
ref={ref}
>
{label}
</span>
)}
</div>
);
});

Checkbox.displayName = 'Checkbox';

export { Checkbox };
42 changes: 42 additions & 0 deletions resources/scripts/components/elements/LabelNew.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from 'react';
import styled from 'styled-components';

interface CheckboxProps {
label?: string;
checked: boolean;
onChange: () => void;
}

const CheckboxWrapper = styled.div`
display: flex;
align-items: center;
gap: 8px;
user-select: none;
`;

const StyledInput = styled.input`
margin-right: 8px;
`;

const StyledLabel = styled.label`
display: flex;
align-items: center;
cursor: pointer;
`;

const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(({ label, checked, onChange }, ref) => {
return (
<CheckboxWrapper>
{label && (
<StyledLabel>
<StyledInput type='checkbox' checked={checked} onChange={onChange} ref={ref} />
<span>{label}</span>
</StyledLabel>
)}
</CheckboxWrapper>
);
});

Checkbox.displayName = 'Checkbox';

export { Checkbox };
11 changes: 11 additions & 0 deletions resources/scripts/components/elements/ModBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';

import { cn } from '@/lib/utils';

const ModBox = React.forwardRef<React.ElementRef<'div'>, React.ComponentPropsWithoutRef<'div'>>(({ ...props }, ref) => {
return <div ref={ref} className='mb-4 w-full text-nowrap select-none' {...props}></div>;
});

ModBox.displayName = 'ModBox';

export { ModBox };
15 changes: 15 additions & 0 deletions resources/scripts/components/elements/ModrinthLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// million-ignore
const Logo = () => {
return (
<svg viewBox='0 0 24 24' version='1.1' id='svg1' width='24' height='24'>
<defs id='defs1' />
<path
d='M4.629 14.971A7.875 7.875 0 0 1 4.051 12c0-4.37 3.553-7.917 7.93-7.917.135 0 .27.003.405.01l-.38 2.151h-.025a5.763 5.763 0 0 0-5.452 7.632l2.346-1.352-.5-1.724 1.923-2.16 2.644-.72.962.96-1.443 1.44-.961.24-.721.96.269 1.018.748.741 1.193-.143.689-.712 1.97-.527.352 1.312-1.946 1.926-2.835.583-1.098-1.141-2.35 1.354a5.755 5.755 0 0 0 4.737 1.801l.566 2.11a7.92 7.92 0 0 1-7.213-2.809l-1.686.972a9.861 9.861 0 0 0 16.694-1.753l2.042.742A12.027 12.027 0 0 1 11.981 24C5.671 24 .49 19.135 0 12.96h2.172a9.78 9.78 0 0 0 .776 2.98l1.681-.969Zm16.51-6.608a9.863 9.863 0 0 0-9.158-6.203c-5.115 0-9.326 3.9-9.809 8.88H0C.49 4.865 5.671 0 11.981 0 18.614 0 24 5.377 24 12c0 1.104-.15 2.173-.43 3.19l-2.042-.742a9.833 9.833 0 0 0 .22-3.763l-1.879.502c.027.268.041.539.041.813 0 3.318-2.048 6.162-4.95 7.339l-.566-2.111A5.758 5.758 0 0 0 17.746 12a5.764 5.764 0 0 0-3.818-5.419l.38-2.151a7.955 7.955 0 0 1 4.955 4.435l1.876-.502Z'
id='path1'
fill='white'
/>
</svg>
);
};

export default Logo;
48 changes: 48 additions & 0 deletions resources/scripts/components/elements/ScrollMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from 'react';

import { Checkbox } from '@/components/elements/CheckboxLabel';

import { cn } from '@/lib/utils';

const ScrollMenu = React.forwardRef<
React.ElementRef<'div'>,
React.ComponentPropsWithoutRef<'div'> & { items: string[] }
>(({ className, items, ...props }, ref) => {
const [checkedItems, setCheckedItems] = React.useState<string[]>([]);

// Handle checkbox change
const handleCheckboxChange = (item: string) => {
// Update the checked state
setCheckedItems((prev) => {
const updatedItems = prev.includes(item) ? prev.filter((i) => i !== item) : [...prev, item];

// Log the name of the item that was selected/deselected
console.log(`${item} is now ${updatedItems.includes(item) ? 'selected' : 'deselected'}`);
console.log(updatedItems);

return updatedItems;
});
};

return (
<div ref={ref} className={cn('relative', className)} {...props}>
<div className='overflow-y-auto max-h-48 scrollbar-thin scrollbar-thumb-[#FF343C] hover:scrollbar-thumb-[#F06F53] scrollbar-track-[#000000]'>
<ul>
{items.map((item) => (
<li key={item}>
<Checkbox
label={item}
// checked={checkedItems.includes(item)} // Set checked state
onChange={() => handleCheckboxChange(item)} // Handle change
/>
</li>
))}
</ul>
</div>
</div>
);
});

ScrollMenu.displayName = 'ScrollMenu';

export { ScrollMenu };
29 changes: 26 additions & 3 deletions resources/scripts/components/elements/inputs/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,31 @@ import { forwardRef } from 'react';

import styles from './styles.module.css';

type Props = Omit<React.ComponentProps<'input'>, 'type'>;
type Props = Omit<React.ComponentProps<'input'>, 'type'> & {
label?: string; // Optional label text for better accessibility
inputField?: boolean; // Optional flag to display an input field
};

export default forwardRef<HTMLInputElement, Props>(({ className, ...props }, ref) => (
<input ref={ref} type={'checkbox'} className={clsx('form-input', styles.checkbox_input, className)} {...props} />
const CheckBox = forwardRef<HTMLInputElement, Props>(({ className, label, inputField, ...props }, ref) => (
<div className={clsx('flex items-center', className)}>
<input
ref={ref}
type='checkbox'
className={clsx(
'form-input',
styles.checkbox_input,
'accent-branding', // Use the custom branding color for the checkbox accent
{
[styles.with_input]: inputField, // Add custom styles when the input field is enabled
},
)}
{...props}
/>
{label && <label className={clsx('ml-2', styles.label)}>{label}</label>}
{inputField && (
<input type='text' className={clsx('ml-2', 'form-input', styles.input_field, 'border-branding')} />
)}
</div>
));

export default CheckBox;
Loading

0 comments on commit 3d0f3c8

Please sign in to comment.