1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-06-25 00:04:15 +02:00
parent be02d05ba8
commit fc7ea910e9
35 changed files with 11992 additions and 1 deletions

View file

@ -0,0 +1,73 @@
import React, { useState, useRef } from "react"
import { DEFAULT_THEME, Paper, Text, Divider, Stack, Button } from '@mantine/core'
import { fetchNui } from "../utils/fetchNui"
import { useNuiEvent } from "../hooks/useNuiEvent"
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import * as Icons from '@fortawesome/free-solid-svg-icons'
import { IconProp } from '@fortawesome/fontawesome-svg-core'
const Dialogue: React.FC = () => {
const theme = DEFAULT_THEME
const [options, setOptions] = useState([])
const [label, setLabel] = useState('')
const [speech, setSpeech] = useState('')
useNuiEvent<any>('dialogue', (data) => {
setOptions(data.options)
setLabel(data.label)
setSpeech(data.speech)
})
const getIconByName = (iconName: string) => {
const formattedName = `fa${iconName.charAt(0).toUpperCase() + iconName.slice(1).replace(/-./g, (m) => m[1].toUpperCase())}`
return Icons[formattedName as keyof typeof Icons] || Icons.faQuestionCircle
}
return (
<div
style={{
width: '100%',
height: '100%',
margin: -8,
position: 'fixed',
display: 'flex',
justifyContent: 'center',
alignItems: 'flex-end',
background: `linear-gradient(180deg, rgba(255, 255, 255, 0) 75%, rgba(0, 0, 0, 0.80) 100%)`
}}
>
<Stack miw={500} maw={1000} m={50} spacing={5}>
<Text size="xl" fw={700} color="white">{label}</Text>
<Paper withBorder p={5} pl={10}>
<Text color="white" size="lg" fw={500}>{speech}</Text>
</Paper>
<Divider />
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
flexWrap: 'wrap',
gap: 10
}}
>
{options.length > 0 && options.map(({ label, icon, id, close, canInteract }) => (
canInteract && <Button
color="gray"
bg={theme.colors.dark[7]}
leftIcon={<FontAwesomeIcon icon={getIconByName(icon) as IconProp} />}
style={{
border: `1px solid ${theme.colors.dark[4]}`
}}
onClick={() => fetchNui('executeAction', { id, options, close })}
>
{label}
</Button>
))}
</div>
</Stack>
</div>
)
}
export default Dialogue

View file

@ -0,0 +1,62 @@
import React, { useState } from "react"
import { DEFAULT_THEME, Paper, Text, Divider, TypographyStylesProvider } from '@mantine/core'
import { useNuiEvent } from "../hooks/useNuiEvent"
const MissionStatus: React.FC = () => {
const theme = DEFAULT_THEME
const [title, setTitle] = useState('')
const [text, setText] = useState('')
useNuiEvent<any>('missionStatus', (data) => {
setTitle(data.title)
setText(data.text)
})
return (
<div
style={{
width: '100%',
height: '100%',
margin: -8,
position: 'fixed',
display: 'flex',
alignItems: 'center'
}}
>
<div
style={{
maxWidth: 400,
position: 'absolute',
left: 20,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
textAlign: 'center',
gap: 5
}}
>
<Text size="xl" color="white" fw={700}>{title}</Text>
<Divider
color="dark.0"
size="lg"
style={{
borderRadius: theme.radius.md
}}
/>
<Paper p={10} withBorder radius="sm">
<TypographyStylesProvider
style={{
textAlign: 'left'
}}
>
<div
dangerouslySetInnerHTML={{ __html: text }}
/>
</TypographyStylesProvider>
</Paper>
</div>
</div>
)
}
export default MissionStatus

View file

@ -0,0 +1,64 @@
import React, { useState } from "react"
import { DEFAULT_THEME, Paper, Text, Kbd } from '@mantine/core'
import { useNuiEvent } from "../hooks/useNuiEvent"
const TextUI: React.FC = () => {
const theme = DEFAULT_THEME
const [key, setKey] = useState('')
const [label, setLabel] = useState('')
const [position, setPosition] = useState('')
useNuiEvent<any>('textUI', (data) => {
setKey(data.key)
setLabel(data.label)
setPosition(data.position)
})
return (
<div
style={{
width: '100%',
height: '100%',
margin: -8,
position: 'fixed',
display: 'flex',
justifyContent: ((position == 'bottom' || position == 'top') ? 'center' : ''),
alignItems: ((position == 'right' || position == 'left') ? 'center' : '')
}}
>
<div
style={{
maxWidth: 400,
position: 'absolute',
bottom: (position == 'bottom' ? 20 : 'auto'),
top: (position == 'top' ? 20 : 'auto'),
right: (position == 'right' ? 20 : 'auto'),
left: (position == 'left' ? 20 : 'auto'),
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
textAlign: 'center',
gap: 5
}}
>
<Paper
withBorder
radius="sm"
p={5}
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'flex-start',
gap: 5
}}
>
<Kbd>{key}</Kbd>
<Text fw={700}>{label}</Text>
</Paper>
</div>
</div>
)
}
export default TextUI

View file

@ -0,0 +1,74 @@
import React, { useState, useEffect } from "react"
import { DEFAULT_THEME, Paper, Text, Progress } from '@mantine/core'
import { fetchNui } from "../utils/fetchNui"
import { useNuiEvent } from "../hooks/useNuiEvent"
const Timer: React.FC = () => {
const theme = DEFAULT_THEME
const [time, setTime] = useState(0)
const [maxTime, setMaxTime] = useState(60)
const [position, setPosition] = useState('')
const [label, setLabel] = useState('')
useNuiEvent<any>('timer', (data) => {
setLabel(data.label)
setTime(data.time)
setMaxTime(data.time)
setPosition(data.position)
})
useEffect(() => {
if (time > 0) {
const timerInterval = setInterval(() => {
setTime((prevTime) => {
if (prevTime <= 1) {
clearInterval(timerInterval)
fetchNui('finishTimer')
return 0
}
return prevTime - 1
})
}, 1000)
return () => clearInterval(timerInterval)
}
}, [time])
return (
<div
style={{
width: '100%',
height: '100%',
margin: -8,
position: 'fixed',
display: 'flex',
justifyContent: ((position == 'bottom' || position == 'top') ? 'center' : ''),
alignItems: ((position == 'right' || position == 'left') ? 'center' : '')
}}
>
<Paper
withBorder
radius="sm"
p={10}
style={{
maxWidth: 400,
position: 'absolute',
bottom: (position == 'bottom' ? 20 : 'auto'),
top: (position == 'top' ? 20 : 'auto'),
right: (position == 'right' ? 20 : 'auto'),
left: (position == 'left' ? 20 : 'auto'),
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
textAlign: 'center',
gap: 5
}}
>
<Text fw={700}>{label}: {time}s</Text>
<Progress w="100%" value={(time / maxTime) * 100} />
</Paper>
</div>
)
}
export default Timer