This commit is contained in:
Nordi98 2025-08-06 16:37:06 +02:00
parent 510e3ffcf2
commit f43cf424cf
305 changed files with 34683 additions and 0 deletions

View file

@ -0,0 +1,82 @@
.container {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
min-height: 100vh;
background: transparent;
}
.dialogue-container {
position: fixed;
bottom: 30px;
width: 50%;
background: transparent;
padding: 25px;
left: 50%;
transform: translateX(-50%);
}
.dialogue-text {
background: rgba(0, 0, 0, 0.85);
padding: 20px;
border-radius: 4px;
margin: 15px 0;
line-height: 1.6;
font-size: 1.1em;
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}
.dialogue-options {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 12px;
justify-content: space-between;
margin-top: 20px;
width: 100%;
}
.dialogue-button {
background: rgba(0, 0, 0, 0.85);
border: 1px solid rgba(255, 255, 255, 0.15);
color: white;
padding: 12px 24px;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
font-size: 0.95em;
flex: 1;
text-align: center;
min-width: calc(33.333% - 8px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}
.dialogue-button:hover {
background: rgba(51, 51, 51, 0.55);
transform: translateY(-1px);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
border: 1px solid rgba(255, 255, 255, 0.3);
}
h2 {
color: #ffffff;
margin: 0;
font-size: 1.4em;
font-weight: 600;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
p {
color: #fff;
margin: 0;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
/* Add this for better text rendering */
* {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

View file

@ -0,0 +1,54 @@
import { useState } from 'react'
import { fetchNui } from './fetch'
import './dialogue.css'
function Dialogue() {
const [count, setCount] = useState(0)
const [dialogueOptions, setDialogueOption] = useState([])
const [currentText, setCurrentText] = useState("Welcome traveler! How can I help you today?")
const [speakerName, setSpeakerName] = useState("Friendly NPC")
const handleMessage = (event) => {
var data = event.data;
if (data !== undefined && data.type === "close") {
document.getElementById('root').classList.add("hidden");
}
if (data !== undefined && data.type === "open") {
setDialogueOption(data.options);
setCurrentText(data.text);
setSpeakerName(data.name);
document.getElementById('root').classList.remove("hidden");
}
};
window.addEventListener("message", handleMessage);
return (
<>
<div className="container">
{/* Dialogue System */}
<div className="dialogue-container">
<h2>{speakerName}</h2>
<div className="dialogue-text">
<p>{currentText}</p>
</div>
<div className="dialogue-options">
{dialogueOptions.map((option) => (
<button
key={option.id}
onClick={() => fetchNui("dialogue:SelectOption", { name: speakerName, id: option.id })}
className="dialogue-button"
>
{option.label}
</button>
))}
</div>
</div>
</div>
</>
)
}
export default Dialogue

View file

@ -0,0 +1,26 @@
export const fetchNui = async (cbName, data = {}) => {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: JSON.stringify(data)
};
try {
const resourceName = window.GetParentResourceName?.() || '';
const resp = await fetch(`https://${resourceName}/${cbName}`, options);
if (!resp.ok) {
throw new Error(`HTTP error! status: ${resp.status}`);
}
return await resp.json();
} catch (error) {
console.error(`Fetch error for ${cbName}:`, error);
if (!window.GetParentResourceName?.()) {
console.error('Resource name is null - are you testing in browser?');
}
return null;
}
};

View file

@ -0,0 +1,9 @@
.hidden {
display: none;
}
* {
overflow-y: hidden;
overflow-x: hidden;
}

View file

@ -0,0 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import Dialogue from './dialogue';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Dialogue />
</React.StrictMode>
);

View file

@ -0,0 +1,14 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import Dialogue from './dialogue.jsx'
import './index.css'
const root = document.getElementById('root')
ReactDOM.createRoot(root).render(
<React.StrictMode>
<Dialogue />
</React.StrictMode>,
)
// add hidden to root element
root.classList.add('hidden')

View file

@ -0,0 +1,3 @@
.hidden {
display: none;
}

View file

@ -0,0 +1,32 @@
import { useState } from 'react'
import './test.css'
function Dialogue() {
const [count, setCount] = useState(0)
const handleMessage = (event) => {
var data = event.data;
if (data !== undefined && data.type === "hide") {
document.getElementById('root').classList.add("hidden");
}
if (data !== undefined && data.type === "open") {
document.getElementById('root').classList.remove("hidden");
}
};
window.addEventListener("message", handleMessage);
return (
<>
<div className="container">
<img src= "https://dunb17ur4ymx4.cloudfront.net/wysiwyg/1364588/7b504ad7f496249800123e36ecfb3905677e337d.png"></img>
<br></br>
<button onClick={() => setCount(count + 1)}>Click me</button>
<p>You clicked {count} times</p>
</div>
</>
)
}
export default Dialogue