Add Sonner component

This commit is contained in:
grimsi
2024-06-07 23:55:15 +02:00
parent 0943ffa265
commit b78e94b45e
7 changed files with 69 additions and 6 deletions
+29
View File
@@ -0,0 +1,29 @@
import { useTheme } from "next-themes"
import { Toaster as Sonner } from "sonner"
type ToasterProps = React.ComponentProps<typeof Sonner>
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme()
return (
<Sonner
theme={theme as ToasterProps["theme"]}
className="toaster group"
toastOptions={{
classNames: {
toast:
"group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
description: "group-[.toast]:text-muted-foreground",
actionButton:
"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
cancelButton:
"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
},
}}
{...props}
/>
)
}
export { Toaster }
+2
View File
@@ -5,6 +5,7 @@ import {ThemeProvider as NextThemesProvider} from "next-themes";
import {themeNames} from "Frontend/theming/themes"; import {themeNames} from "Frontend/theming/themes";
import {AuthProvider} from "Frontend/util/auth"; import {AuthProvider} from "Frontend/util/auth";
import {IconContext} from "@phosphor-icons/react"; import {IconContext} from "@phosphor-icons/react";
import {Toaster} from "Frontend/@/components/ui/sonner";
export default function App() { export default function App() {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -15,6 +16,7 @@ export default function App() {
<AuthProvider> <AuthProvider>
<IconContext.Provider value={{size: 20}}> <IconContext.Provider value={{size: 20}}>
<Outlet/> <Outlet/>
<Toaster/>
</IconContext.Provider> </IconContext.Provider>
</AuthProvider> </AuthProvider>
</NextThemesProvider> </NextThemesProvider>
+2
View File
@@ -8,6 +8,7 @@ import {Card} from "@nextui-org/react";
import {SetupEndpoint} from "Frontend/generated/endpoints"; import {SetupEndpoint} from "Frontend/generated/endpoints";
import {ThemeSelector} from "Frontend/components/theming/ThemeSelector"; import {ThemeSelector} from "Frontend/components/theming/ThemeSelector";
import {useNavigate} from "react-router-dom"; import {useNavigate} from "react-router-dom";
import {toast} from "sonner";
function WelcomeStep() { function WelcomeStep() {
return ( return (
@@ -99,6 +100,7 @@ function SetupView() {
password: values.password, password: values.password,
email: values.email email: values.email
}); });
toast("Setup finished", {description: "Have fun with Gameyfin!"});
navigate('/login'); navigate('/login');
} catch (e) { } catch (e) {
alert("An error occurred while completing the setup. Please try again.") alert("An error occurred while completing the setup. Please try again.")
+13 -1
View File
@@ -1,9 +1,21 @@
import {Link} from "react-router-dom"; import {Link} from "react-router-dom";
import {Button} from "@nextui-org/react";
import {toast} from "sonner";
export default function TestView() { export default function TestView() {
return ( return (
<div className="flex grow justify-center"> <div className="flex grow justify-center mt-12">
<div className="flex flex-col items-center gap-6">
<Link to="/setup">Setup</Link> <Link to="/setup">Setup</Link>
<Button onPress={
() => toast("Setup finished", {
description: "Have fun with Gameyfin!",
action: {
label: "OK",
onClick: () => console.log("Ok"),
}
})}>Toast</Button>
</div>
</div> </div>
); );
} }
+12
View File
@@ -41,6 +41,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.4.2", "react-router-dom": "^6.4.2",
"sonner": "^1.4.41",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",
"yup": "^1.4.0" "yup": "^1.4.0"
}, },
@@ -10677,6 +10678,7 @@
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz",
"integrity": "sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==", "integrity": "sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==",
"license": "MIT",
"peerDependencies": { "peerDependencies": {
"react": "^16.8 || ^17 || ^18", "react": "^16.8 || ^17 || ^18",
"react-dom": "^16.8 || ^17 || ^18" "react-dom": "^16.8 || ^17 || ^18"
@@ -12102,6 +12104,16 @@
"atomic-sleep": "^1.0.0" "atomic-sleep": "^1.0.0"
} }
}, },
"node_modules/sonner": {
"version": "1.4.41",
"resolved": "https://registry.npmjs.org/sonner/-/sonner-1.4.41.tgz",
"integrity": "sha512-uG511ggnnsw6gcn/X+YKkWPo5ep9il9wYi3QJxHsYe7yTZ4+cOd1wuodOUmOpFuXL+/RE3R04LczdNCDygTDgQ==",
"license": "MIT",
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/sort-asc": { "node_modules/sort-asc": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz", "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz",
+4 -2
View File
@@ -36,6 +36,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.4.2", "react-router-dom": "^6.4.2",
"sonner": "^1.4.41",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",
"yup": "^1.4.0" "yup": "^1.4.0"
}, },
@@ -100,7 +101,8 @@
"tailwind-merge": "$tailwind-merge", "tailwind-merge": "$tailwind-merge",
"@nextui-org/react": "$@nextui-org/react", "@nextui-org/react": "$@nextui-org/react",
"framer-motion": "$framer-motion", "framer-motion": "$framer-motion",
"@material-tailwind/react": "$@material-tailwind/react" "@material-tailwind/react": "$@material-tailwind/react",
"sonner": "$sonner"
}, },
"vaadin": { "vaadin": {
"dependencies": { "dependencies": {
@@ -144,6 +146,6 @@
"workbox-core": "7.0.0", "workbox-core": "7.0.0",
"workbox-precaching": "7.0.0" "workbox-precaching": "7.0.0"
}, },
"hash": "a2234ddab9db9a07cd47eded5c9642efac70874179c7dadb6c6887c4fe6519a7" "hash": "3305a1ae01d771a26115b08f2597b5fbb020e6535692fd453407cba700f727ea"
} }
} }
@@ -9,26 +9,30 @@ import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.transaction.Transactional import jakarta.transaction.Transactional
import org.springframework.boot.context.event.ApplicationReadyEvent import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.context.event.EventListener import org.springframework.context.event.EventListener
import org.springframework.core.env.Environment
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import java.net.InetAddress
@Service @Service
@Transactional @Transactional
class SetupDataLoader( class SetupDataLoader(
private val roleRepository: RoleRepository, private val roleRepository: RoleRepository,
private val userService: UserService private val userService: UserService,
private val env: Environment
) { ) {
private val log = KotlinLogging.logger {} private val log = KotlinLogging.logger {}
@EventListener(ApplicationReadyEvent::class) @EventListener(ApplicationReadyEvent::class)
fun initialSetup() { fun initialSetup() {
log.info { "Looks like this is the first time your're starting Gameyfin." } log.info { "Looks like this is the first time you're starting Gameyfin." }
log.info { "We will now set up some data..." } log.info { "We will now set up some data..." }
setupRoles() setupRoles()
//setupUsers() //setupUsers()
log.info { "Setup completed..." } log.info { "Setup completed..." }
log.info { "Visit http://${InetAddress.getLocalHost().hostName}:${env.getProperty("server.port")}/setup to complete the setup" }
} }
fun setupUsers() { fun setupUsers() {