mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-11 16:45:13 +00:00
# Which Problems Are Solved - The previous monorepo in monorepo structure for the login app and its related packages was fragmented, complicated and buggy. - The process for building and testing the login container was inconsistent between local development and CI. - Lack of clear documentation as well as easy and reliable ways for non-frontend developers to reproduce and fix failing PR checks locally. # How the Problems Are Solved - Consolidated the login app and its related npm packages by moving the main package to `apps/login/apps/login` and merging `apps/login/packages/integration` and `apps/login/packages/acceptance` into the main `apps/login` package. - Migrated from Docker Compose-based test setups to dev container-based setups, adding support for multiple dev container configurations: - `.devcontainer/base` - `.devcontainer/turbo-lint-unit` - `.devcontainer/turbo-lint-unit-debug` - `.devcontainer/login-integration` - `.devcontainer/login-integration-debug` - Added npm scripts to run the new dev container setups, enabling exact reproduction of GitHub PR checks locally, and updated the pipeline to use these containers. - Cleaned up Dockerfiles and docker-bake.hcl files to only build the production image for the login app. - Cleaned up compose files to focus on dev environments in dev containers. - Updated `CONTRIBUTING.md` with guidance on running and debugging PR checks locally using the new dev container approach. - Introduced separate Dockerfiles for the login app to distinguish between using published client packages and building clients from local protos. - Ensured the login container is always built in the pipeline for use in integration and acceptance tests. - Updated Makefile and GitHub Actions workflows to use `--frozen-lockfile` for installing pnpm packages, ensuring reproducible installs. - Disabled GitHub release creation by the changeset action. - Refactored the `/build` directory structure for clarity and maintainability. - Added a `clean` command to `docks/package.json`. - Experimentally added `knip` to the `zitadel-client` package for improved linting of dependencies and exports. # Additional Changes - Fixed Makefile commands for consistency and reliability. - Improved the structure and clarity of the `/build` directory to support seamless integration of the login build. - Enhanced documentation and developer experience for running and debugging CI checks locally. # Additional Context - See updated `CONTRIBUTING.md` for new local development and debugging instructions. - These changes are a prerequisite for further improvements to the CI pipeline and local development workflow. - Closes #10276
75 lines
2.4 KiB
TypeScript
75 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import { setLanguageCookie } from "@/lib/cookies";
|
|
import { Lang, LANGS } from "@/lib/i18n";
|
|
import {
|
|
Listbox,
|
|
ListboxButton,
|
|
ListboxOption,
|
|
ListboxOptions,
|
|
} from "@headlessui/react";
|
|
import { CheckIcon, ChevronDownIcon } from "@heroicons/react/24/outline";
|
|
import clsx from "clsx";
|
|
import { useLocale } from "next-intl";
|
|
import { useRouter } from "next/navigation";
|
|
import { useState } from "react";
|
|
|
|
export function LanguageSwitcher() {
|
|
const currentLocale = useLocale();
|
|
|
|
const [selected, setSelected] = useState(
|
|
LANGS.find((l) => l.code === currentLocale) || LANGS[0],
|
|
);
|
|
|
|
const router = useRouter();
|
|
|
|
const handleChange = async (language: Lang) => {
|
|
setSelected(language);
|
|
const newLocale = language.code;
|
|
|
|
await setLanguageCookie(newLocale);
|
|
|
|
router.refresh();
|
|
};
|
|
|
|
return (
|
|
<div className="w-32">
|
|
<Listbox value={selected} onChange={handleChange}>
|
|
<ListboxButton
|
|
className={clsx(
|
|
"relative block w-full rounded-lg bg-black/5 py-1.5 pl-3 pr-8 text-left text-sm/6 text-black dark:bg-white/5 dark:text-white",
|
|
"focus:outline-none data-[focus]:outline-2 data-[focus]:-outline-offset-2 data-[focus]:outline-white/25",
|
|
)}
|
|
>
|
|
{selected.name}
|
|
<ChevronDownIcon
|
|
className="group pointer-events-none absolute right-2.5 top-2.5 size-4"
|
|
aria-hidden="true"
|
|
/>
|
|
</ListboxButton>
|
|
<ListboxOptions
|
|
anchor="bottom"
|
|
transition
|
|
className={clsx(
|
|
"w-[var(--button-width)] rounded-xl border border-black/5 bg-background-light-500 p-1 [--anchor-gap:var(--spacing-1)] focus:outline-none dark:border-white/5 dark:bg-background-dark-500",
|
|
"transition duration-100 ease-in data-[leave]:data-[closed]:opacity-0",
|
|
)}
|
|
>
|
|
{LANGS.map((lang) => (
|
|
<ListboxOption
|
|
key={lang.code}
|
|
value={lang}
|
|
className="group flex cursor-default select-none items-center gap-2 rounded-lg px-3 py-1.5 data-[focus]:bg-black/10 dark:data-[focus]:bg-white/10"
|
|
>
|
|
<CheckIcon className="invisible size-4 group-data-[selected]:visible" />
|
|
<div className="text-sm/6 text-black dark:text-white">
|
|
{lang.name}
|
|
</div>
|
|
</ListboxOption>
|
|
))}
|
|
</ListboxOptions>
|
|
</Listbox>
|
|
</div>
|
|
);
|
|
}
|