Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I Want To Have a Toggle Switch For Dark & Light theme, How Do i Do it ?. #8

Open
ayhamDev opened this issue Jun 22, 2023 · 2 comments

Comments

@ayhamDev
Copy link

No description provided.

@ayhamDev ayhamDev changed the title I Want To Have a Toggle Switch For Dark & Light them, How Do i Do it ?. I Want To Have a Toggle Switch For Dark & Light theme, How Do i Do it ?. Jun 22, 2023
@dziraf
Copy link
Contributor

dziraf commented Sep 18, 2023

You can for example override SidebarFooter:
componentLoader.override('SidebarFooter', <path to your file>)

SidebarFooter:

import React, { useCallback } from 'react';
import { useCurrentAdmin } from 'adminjs';
import axios from 'axios';
import { Box, Button, Icon } from '@adminjs/design-system';
import { styled, useTheme } from '@adminjs/design-system/styled-components';

const SidebarFooter: React.FC = () => {
  const [currentAdmin, setCurrentAdmin] = useCurrentAdmin();
  const theme = useTheme();

  const toggleTheme = useCallback(async () => {
    try {
      const theme = currentAdmin.theme === 'light' ? 'dark' : 'light';
      const response = await axios.put('/app/me', { theme });

      const { updated, session } = response.data;
      if (updated) {
        setCurrentAdmin(session);
        window.location.reload();
      }
    } catch (err) {
      console.error(err);
    }
  }, [currentAdmin]);

  const icon = currentAdmin.theme === 'dark' ? 'Sun' : 'Moon';

  return (
    <Box mt="lg" mb="md" data-css="sidebar-footer">
      <Box flex justifyContent="center" mb="xl">
        <ToggleButton onClick={toggleTheme} size="icon">
          <Icon icon={icon} size={24} color={theme.colors.text} />
        </ToggleButton>
      </Box>
    </Box>
  );
};

export default SidebarFooter;

This will handle the frontend, but you need to add a new adminjs endpoint which modifies your user's session.

Express example (a file where you create AdminJS router):

  const router = ExpressPlugin.buildAuthenticatedRouter(
    admin,
    // other settings
  );

  router.put('/me', (request, response) => {
    const body = (request as any).fields ?? {};
    const admin = { ...((request.session as any).adminUser ?? {}) };

    let sessionUpdated = false;
    // It's better to set all relevant values manually to avoid malforming the session object
    if (body.theme) {
      admin.theme = body.theme;

      (request.session as any).adminUser = admin;
      request.session.save();
      sessionUpdated = true;
    }

    return response.send({
      session: admin,
      updated: sessionUpdated,
    });
  });
Screen.Recording.2023-09-18.at.12.53.23.mov

@thiagovt-dev
Copy link

Hi, first, thank you for your solution, but I tried this solution and i had this error

'useTheme' is declared but its value is never read.ts(6133) Module '"@adminjs/design-system/styled-components"' has no exported member 'useTheme'. Did you mean to use 'import useTheme from "@adminjs/design-system/styled-components"' instead?ts(2614) import useTheme

in

import { styled, useTheme } from '@adminjs/design-system/styled-components';

At the moment, I'm using adminJs 7.8.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants