Conditional render with svelte kit for protect routes with token of sessionStorage - session

Im trying to generate a conditional render for protect routes with token. But i have the problem that when i enter the route with token first, for one second, is rendered the error page.
Code:
<script>
import Successlogin from '$lib/Login/Successlogin.svelte';
import { browserLocalGet, browserGet } from '$lib/Browser/index';
import ErrorPage from '$lib/ErrorPage/index.svelte';
import { writable } from 'svelte/store';
let routeSecurity = writable({
accessToken: browserGet('accessToken'),
emailForVerify: browserLocalGet('emailForSignIn')
});
</script>
{#if $routeSecurity.accessToken || $routeSecurity.emailForVerify}
<Successlogin />
{:else}
<ErrorPage
status={403}
title="Forbidden Access"
description="Please, check that you are login."
/>
{/if}

Related

Why is usePage().url returning ComputedRefImpl?

I have the following vue page:
<template>
<a :class="isCurrent($page.url)"
</template>
<script setup>
import {usePage} from '#inertiajs/inertia-vue3'
const isCurrent = (url) => {
console.log(url);
console.log(usePage().url);
};
</script>
The url of the page is /comment and if I inspect the page I find exactly that:
However, on the console log, the url is not displayed correctly:
While I can access the page correctly inside the template section using $page.url I cant access it within <script setup> usePage() creates a document where everything is ComputedRefImpl:
How can I access the page object using usePage() without having to pass $page from the template section?
You need to add .value, similiar as with ref https://vuejs.org/api/reactivity-core.html#ref
<script setup>
import {usePage} from '#inertiajs/inertia-vue3'
const isCurrent = (url) => {
console.log(url);
console.log(usePage().url.value);
};
</script>
You need to access the page props ref before accessing url.
usePage().props.value.url

Remix.run - common shared components

I’m just getting started learning remix.run and whilst I’ve gone through the tutorials there’s one bit I’m stuck on how I should implement it in remix.
If I wanted to display a common header that might toggle a sign in/sign out button based on the users logged in state where would this live?
My nextjs thinking would be to create the components and reference them in the common document. I know I can do this in the remix.server and remix.client files, but as my “login” component is and isn’t a route (I.e I might want to POST to the route when a user submits the login form but GET /login isn’t really a route) how would you structure something like this and would doing this even allow me to have loader and action functions in the shared component?
Do I just need to adjust my thinking about how to achieve this in remix or am I overthinking it and the above is perfectly valid?
I tried the following and it works. But then I end up just creating an empty "logout" route to process the form data with an action and loader that process the form in the case of the action or just redirect if a GET request via the loader. Is this the best approach?
export const SignIn = ({user}) => {
return (
<>
<form method="POST"action="/logout">
<input type="hidden" id="some" value="foo" />
{user ?
(
<button>sign out</button>
)
: (
<button>sign in</button>
)
}
</form>
</>
)
}
Thanks
based on https://remix.run/docs/en/v1/tutorials/jokes#build-the-login-form
it does indeed look like an empty route for logout:
import type { ActionFunction, LoaderFunction } from "#remix-run/node"
import { redirect } from "#remix-run/node"
import { logout } from "~/utils/session.server"
export const action: ActionFunction = async ({request}) => {
return logout(request);
};
export const loader: LoaderFunction = async () => {
return redirect("/");
};

How to Change Navbar Component Link Buttons Based on User being Logged in or Logged out using JavaScript and React JSX

I am trying to have the navigation component in React change from Login to Logout after the user logs in to their profile page.
I am loading the pages in my localhost while in development. The user can already log in successfully. I have tried importing the loggedIn method from my auth.js file in my utils folder on the client side. I then placed a conditional of if logged in then render the Logout link else render the Login and Sign Up link/button. VScode is giving me errors once I place the else conditional in the JSX. What am I doing wrong?
Here is the code for my Navigation.js Component:
import "bootstrap/dist/css/bootstrap.css";
import { Container, Nav, Navbar, Button } from "react-bootstrap";
import siteLogo from "../../assets/images/logo.png";
import loggedIn from '../../utils/auth';
function Navigation() {
return (
<div className="App">
<Navbar
bg="dark"
variant="dark"
sticky="top"
expand="sm"
collapseOnSelect
>
<Container>
<Navbar.Brand>
<Nav.Link href="/">
<img alt="" src={siteLogo} className="site-logo"></img>
</Nav.Link>
</Navbar.Brand>
<Navbar.Toggle />
<Navbar.Collapse>
<Nav className="me-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="/about">About</Nav.Link>
<Nav.Link href="/contact">Contact</Nav.Link>
</Nav>
<Nav>
{{if:loggedIn}}
<Nav.Link href="/">Logout</Nav.Link>
{{else}}
<Nav.Link href="/signin">Login</Nav.Link>
<Button href="/signup" className="mx-2" variant="primary">
Sign up
</Button>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</div>
);
}
export default Navigation;
Here is the code for my Auth.js utils:
import decode from 'jwt-decode';
class AuthService {
getProfile() {
return decode(this.getToken());
}
loggedIn() {
// Checks if there is a saved token and it's still valid
const token = this.getToken();
return !!token && !this.isTokenExpired(token); // handwaiving here
}
isTokenExpired(token) {
try {
const decoded = decode(token);
if (decoded.exp < Date.now() / 1000) {
return true;
} else return false;
} catch (err) {
return false;
}
}
getToken() {
// Retrieves the user token from localStorage
return localStorage.getItem('id_token');
}
login(idToken) {
// Saves user token to localStorage
localStorage.setItem('id_token', idToken);
window.location.assign('/Profile');
}
logout() {
// Clear user token and profile data from localStorage
// axios.defaults.headers.common["Authorization"] = null;
localStorage.removeItem('id_token');
// this will reload the page and reset the state of the application
window.location.assign('/');
}
}
export default new AuthService();
Here is a screenshot of the navigation after the user has already logged in:
I'm still working on the profile page itself, so please ignore the white space.
you can use conditional rendering, Here you can find the documentation

How can I programatically show/hide editLink client side in Vuepress 2?

I want to show the edit link only for privileged users. I have user information that I am using for example for routing, and I can use it in components. However, I have not found any way to show/hide the edit link on each page based on the user roles. It must be done client side. Please help.
I found a way to do this:
Follow the instructions to extend the default theme.
Make your own EditLink component like this:
// EditLink.vue
<template></template>
<script setup>
import { onMounted } from "vue";
import { usePageFrontmatter } from "#vuepress/client";
onMounted(() => {
const fm = usePageFrontmatter();
fm.value.editLink = true; // Replace true with your logic
});
</script>
In the Layout component (see instructions linked above) do this:
// Layout.vue
<template>
<Layout>
<template #page-bottom> <EditLink /></template>
</Layout>
</template>
<script setup>
import Layout from "#vuepress/theme-default/lib/client/layouts/Layout.vue";
import EditLink from "../components/EditLink";
</script>

Routing Issues in React-Redux

I'm new to the React-Redux ecosystem, learning by trying out simple applications.
In this case I'm trying out how routing works in the react-redux application.
Basically, the idea is :
Navigate to a new page by clicking a Link( a react-router
component)
Navigate to a new page upon successful completion of dispatched async action.
Here's my code
import React from 'react'
import {Link} from 'react-router'
import {routerActions} from 'react-router-redux'
import {connect} from 'react-redux'
class App extends React.Component {
render() {
// And you have access to the selected fields of the State too!
return (
<div>
<header>
Links:
{' '}
<Link to="/">Home</Link>
{' '}
<Link to="/foo">Foo</Link>
{' '}
<Link to="/bar">Bar</Link>
</header>
<div>
<button onClick={() => routerActions.push('/foo')}>Go to /foo</button>
</div>
</div>
)
}
}
export default connect(null, null)(App);
===================================================================
import React from 'react'
import {connect} from 'react-redux'
class Foo extends React.Component {
render() {
return (
<div> <h1>I'm Foo</h1> </div>
)
}
}
export default connect(null, null)(Foo);
===================================================================
import React from 'react'
import {connect} from 'react-redux'
class Bar extends React.Component {
render() {
return (
<div> <h1>I'm bar</h1> </div>
)
}
}
export default connect(null, null)(Bar);
===================================================================
import React from 'react'
import ReactDOM from 'react-dom'
import {Provider} from 'react-redux'
import {Router, Route, browserHistory} from 'react-router'
import {syncHistoryWithStore} from 'react-router-redux'
import configureStore from './store'
import App from './components/test/App';
import Bar from './components/test/Bar';
import Foo from './components/test/Foo';
// Get the store with integrated routing middleware.
const store = configureStore()
// Sync browser history with the store.
const history = syncHistoryWithStore(browserHistory, store)
// And use the prepared history in your Router
ReactDOM.render(
<Provider store={store}>
<div>
<Router history={history}>
<Route path="/" component={App}>
<Route path="/foo" component={Foo}/>
<Route path="/bar" component={Bar}/>
</Route>
</Router>
</div>
</Provider>,
document.getElementById('root')
===================================================================
import {combineReducers,createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import userReducer from './reducers/reducer-user';
import {routerMiddleware,routerReducer} from 'react-router-redux'
import {browserHistory} from 'react-router'
export default function configureStore() {
// Create the routing middleware applying it history
const browserMiddleware = routerMiddleware(browserHistory);
const logger = createLogger();
const reducer = combineReducers({
userState: userReducer,
routing: routerReducer
})
const store = createStore(reducer,applyMiddleware(thunk,browserMiddleware,logger));
return store;
}
The application builds fine and it comes up well but when i click on the link, it does not work.
See screen shot of the running application
Searched around and read various posts but i could not pinpoint the root problem.
Your code seems to be correct, but there is a simple thing you are missing: you are not rendering the "child" of your router! :)
You can check that out here:
https://github.com/reactjs/react-router-tutorial/tree/master/lessons/04-nested-routes#sharing-our-navigation
Whenever you want to render a component route (the one you declared using </Route path="application-path" component={MyComponent} />), you need to specify where it will be placed. Using react-router, you specify this using the children prop. Then, whenever React "sees" this prop, it will render your routes (it can be a nested route too).
So, to fix your code, your App component needs to handle this.props.children correctly. Something like that:
class App extends React.Component {
/* ... */
render() {
return (
<div>
<header>Links go here</header>
{this.props.children}
</div>
)
}
}
Now, when you hit "/foo" route, this.props.children will be replaced by Foo component.
By the way, your nested routes (those inside ) don't need to have "/", since they will be "prepended". This is the way react-router render nested routes.
I think that is it, good luck with that! :)

Resources