Skip to content

Commit

Permalink
updated navleft
Browse files Browse the repository at this point in the history
  • Loading branch information
ilkhoeri committed Feb 5, 2025
1 parent 0cc1598 commit 6fb73df
Show file tree
Hide file tree
Showing 16 changed files with 268 additions and 244 deletions.
12 changes: 6 additions & 6 deletions .contentlayer/.cache/v0.5.3/data-FCKZZ7R7.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .contentlayer/generated/Docs/_index.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .contentlayer/generated/Docs/toc.mdx.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3146,7 +3146,10 @@ code[data-line-numbers-max-digits="3"] > [data-line]::before {
}

& :where(:is(h1, )):not(:is([data-demo-area] :is(h1))) {
@apply text-color leading-none mb-6 mt-0 flex items-center cursor-default w-max [&>a>svg]:hover:text-constructive max-w-full;
@apply text-color leading-none mb-[2.1rem] mt-0 flex items-center cursor-default w-max [&>a>svg]:hover:text-constructive max-w-full;
& ~ ul ul li a {
@apply text-constructive-emphasis transition-colors underline-hover;
}
}

& :where(:is(h2, h3, h4, h5)):not(:is([data-demo-area] :is(h2, h3, h4, h5))) {
Expand Down
39 changes: 30 additions & 9 deletions lib/text-parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
const DEFAULT_CONJUNCTIONS = ["and", "or", "of", "the", "this", "with", "dan", "atau", "yang", "untuk", "di", "ke", "dari", "oleh", "pada"];

export type FormatName = keyof typeof transform;

/** Transforms a given string based on the specified transformation type. */
export const transform = Object.assign(
{},
{
/**
* @param words - The input string to transform.
* @returns string
*/
unformated: (words: string | undefined) => {
if (!words) return "";
return words;
},
/**
* @param words - The input string to transform.
* @returns string
*/
uppercaseFirst: (words: string | undefined) => {
if (!words) return "";
return words
.toLowerCase()
.split(" ")
.map((word, index) => (index === 0 || !DEFAULT_CONJUNCTIONS.includes(word) ? toUpper(word) : word))
.join(" ");
},
/**
* @param words - The input string to transform.
* @returns string
Expand Down Expand Up @@ -67,8 +91,6 @@ export function truncate(word: string, maxWord: number = 30): string {
return slicedWords;
}

const DEFAULT_CONJUNCTIONS = ["and", "or", "of", "the", "this", "with", "dan", "atau", "yang", "untuk", "di", "ke", "dari", "oleh"];

/**
*
* @param name The John of Doe
Expand Down Expand Up @@ -283,19 +305,18 @@ export const htmlCharacterEntities = [
{ char: " ", entity: " " }
];

type NameFormat = "uppercase" | "capitalizeFirst" | "capitalize" | "lowercase" | "unformated";
export function displayName(title: string, format: NameFormat = "capitalize") {
export function displayName(title: string, format: FormatName = "capitalize") {
const numberRgx = /^(\d+\.)\s*(.+)/;
const cleanTitle = title.replace(":", "").replace("?", "").trim();
const cleanTitle = title?.replace(":", "").replace("?", "").trim();

// Jika formatnya [0.0.0] - YYYY-MM-DD, ubah menjadi v0.0.0
const versionMatch = title.match(/^\[(\d+\.\d+\.\d+)\]\s*-\s*\d{4}-\d{2}-\d{2}$/);
if (versionMatch) return `v${versionMatch[1]}`;
// untuk format [0.0.0] - YYYY-MM-DD
const versionMatch = title?.match(/^\[(\d+\.\d+\.\d+)\]\s*-\s*\d{4}-\d{2}-\d{2}$/);
if (versionMatch) return `v${versionMatch[1]}`; // ubah menjadi v0.0.0

if (numberRgx.test(cleanTitle)) return cleanTitle;

const emojiRgx = /[\p{Emoji}\u200B-\u200D\uFE0F]\s/gu;
if (emojiRgx.test(cleanTitle)) return cleanTitle.replace(emojiRgx, "");

return format !== "unformated" ? transform[format](cleanTitle) : cleanTitle;
return transform[format](cleanTitle);
}
6 changes: 6 additions & 0 deletions md/toc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ date: 2025-02-05
- [How inferType Works](/types#how-infertype-works)
- [Example Usage](/types#example-usage)
- [When to Use inferType](/types#when-to-use-infertype)
- [**Meta**](/meta#meta)
- [Documentation](/meta#documentation)
- [Repository](/meta#repository)
- [Installation](/meta#installation)
- [Bundles](/meta#bundles)
- [Score and Test](/meta#score-and-test)
- [**Exported**](/exported#exported)
- [Using Named and Default Exports Together](/exported#using-named-and-default-exports-together)
- [For ES Modules Users](/exported#for-es-modules-users)
Expand Down
48 changes: 29 additions & 19 deletions routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,11 @@ export type SingleRoute = { title: string; href?: string; data: InnerRoutes[] };
export type NestedRoute = { title: string; href?: string; data: SingleRoute[] };

export const ROUTES = {
services: [
{
title: "Component",
href: "https://oeri.vercel.app"
}
],
docsHead: [
services: [] as InnerRoutes[],
docs: [
{ title: "Table of Contents", href: "/toc" },
{ title: "Getting Started", href: "/started" },
{ title: "Installation", href: "/installation" }
] as InnerRoutes[],
docs: [
{ title: "Installation", href: "/installation" },
{
title: "Usage",
href: "/ocx",
Expand All @@ -39,12 +32,7 @@ export const ROUTES = {
{ title: "links", href: "/links" }
]
}
// {
// title: "About",
// href: "/about",
// data: [{ title: "About app", href: "/about/app" }]
// }
] as SingleRoute[],
] as (InnerRoutes | SingleRoute | NestedRoute)[],
sections: [
{
label: "Github Repository",
Expand Down Expand Up @@ -78,9 +66,31 @@ export const ROUTES = {
footRoutes: [] as InnerRoutes[]
};

export const tocList = [...ROUTES["docsHead"].map(d => d.href), ...ROUTES["docs"].flatMap(d => d.data.map(item => item.href))]
.map(href => href.slice(1)) // Menghapus karakter "/" di awal
.filter(href => href !== "toc"); // Mengecualikan "toc"
// Mengambil semua href dari docs secara rekursif
function extractHrefs(routes: (InnerRoutes | SingleRoute | NestedRoute)[]): string[] {
const seen = new Set<string>();
const result: string[] = [];

const traverse = (items: (InnerRoutes | SingleRoute | NestedRoute)[]) => {
for (const item of items) {
if (item.href) {
const cleanHref = item.href.slice(1); // Hilangkan "/" di awal
if (!seen.has(cleanHref)) {
seen.add(cleanHref);
result.push(cleanHref);
}
}
if ("data" in item) {
traverse(item.data); // Rekursi ke dalam `data`
}
}
};

traverse(routes);
return result;
}

export const tocList = extractHrefs(ROUTES["docs"]).filter(href => href !== "toc");

type RouteMap = Record<string, { page: string }>;

Expand Down
29 changes: 27 additions & 2 deletions scripts/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,31 @@ function nameFile(fileSource: string) {
return file[file.length - 1];
}

/**
* expecting a folder structure like the following:
* ```md
* cretex
* ├── main (module root)
* │ ├── CHANGELOG.md
* │ ├── CODE_OF_CONDUCT.md
* │ ├── CONTRIBUTING.md
* │ ├── LICENSE
* │ │
* │ └── // others folder and files...
* │
* ├── docs (docs root)
* │ ├── md
* │ │ ├── file-1.mdx
* │ │ ├── file-2.mdx
* │ │ └── // others files...
* │ │
* │ └── // others folder and files...
* │
* └── // end...
* ```
* @param meta {@link SyncCopyProps SyncCopyProps}
* @returns void
*/
function syncCopy(meta: SyncCopyProps) {
const { title, date, fileSource, fileOutput } = meta;
const sourcePath = path.resolve(__dirname, fileSource);
Expand All @@ -37,9 +62,9 @@ function syncCopy(meta: SyncCopyProps) {

fs.writeFileSync(targetPath, newContent, "utf-8");

console.info(`Synchronized ${title} from ${nameFile(fileSource)} to ${nameFile(fileOutput)} successfully.`);
console.info(`\n✅ Synchronized ${title} from [${nameFile(fileSource)}] to [${nameFile(fileOutput)}] Successfully.\n`);
} catch (error) {
console.error("Error:", error);
console.error("Error:", `\n${error}\n`);
}
}

Expand Down
27 changes: 17 additions & 10 deletions scripts/generateToc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function extractHeadingsFromFile(filePath: string) {
// return toc;
// }

// Fungsi untuk membuat Table of Contents berdasarkan daftar `tocList`
// Membuat Table of Contents berdasarkan daftar `tocList`
function generateTableOfContents(files: string[] = tocList) {
let toc = `# Table of Contents\n\n---\n\n`;

Expand Down Expand Up @@ -130,29 +130,36 @@ function generateTableOfContents(files: string[] = tocList) {
}
});

console.log("Running Generated List:", files);

return toc;
}

interface GenerateTocFileProps {
title: string;
date: Date | string | number;
}
// Fungsi untuk menghasilkan file TOC.mdx

// Menghasilkan file toc.mdx
function generateTocFile({ title, date }: GenerateTocFileProps) {
// const mdxFiles = fs.readdirSync("md").filter(file => file.endsWith(".mdx"));
const toc = generateTableOfContents();
try {
const toc = generateTableOfContents();

const tocFilePath = path.join("md", "toc.mdx");

const tocFilePath = path.join("md", "toc.mdx");
const yamlMetadata = `---\ntitle: ${title}\ndate: ${date}\n---`;
const content = `${yamlMetadata}\n\n${toc.trim()}\n`;

const yamlMetadata = `---\ntitle: ${title}\ndate: ${date}\n---`;
const content = `${yamlMetadata}\n\n${toc.trim()}\n`;
fs.writeFileSync(tocFilePath, content, "utf-8");

fs.writeFileSync(tocFilePath, content, "utf-8");
console.log("✅ Table of Contents has been generated at 'md/toc.mdx'");
console.info(`\n✅ ${title} has been generated at ${tocFilePath}\n`);
} catch (error) {
console.error("Error:", `\n${error}\n`);
}
}

const date = new Intl.DateTimeFormat("en-CA").format(new Date());
// Jalankan fungsi untuk menghasilkan Table of Contents

generateTocFile({
title: "Table of Contents",
date
Expand Down
16 changes: 6 additions & 10 deletions ui/config/app-context.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"use client";
import * as React from "react";
import { CookiesName, setCookies, useCookies } from "./cookies";
import { Cookies } from "./types";
import { useDirection, type Direction } from "@/hooks/use-direction";
import { Cookies } from "./types";

export enum Booleanish {
true = "true",
false = "false"
}

export type CookiesName = `${Cookies}` | (string & {});
type Theme = "dark" | "light" | "system";
type __T_ = "dir" | "theme" | "isOpenAside"; // cookies value
type IntrinsicAppProvider = Partial<Record<__T_, string | undefined>>;
Expand All @@ -18,8 +19,7 @@ interface AppProviderProps extends IntrinsicAppProvider {
interface CtxProps {
openAside: `${Booleanish}`;
setOpenAside: (v: `${Booleanish}`) => void;
// setCookies(name: `${Cookies}` | (string & {}), value: string): Promise<void>;
useCookies<T extends string>(name: CookiesName, initial: T): readonly [string, (value: string, days?: number) => void];
setCookies?: (name: CookiesName, value: string) => Promise<void>;
toggleDirection: () => void;
setDirection: (dir: Direction) => void;
// initial type
Expand All @@ -39,11 +39,7 @@ export const useApp = () => {
};

function useAppFuntions(_app: useAppProps) {
const [initialisOpenAside] = useCookies("__is_open_aside", "true");
const [initialTheme] = useCookies("__theme", "system");
const [initialDirection] = useCookies("__dir", "ltr");

const { isOpenAside = initialisOpenAside, theme = initialTheme, dir = initialDirection, ...others } = _app;
const { isOpenAside = "true", theme = "system", dir = "ltr", ...others } = _app;
const [openAside, setOpenAside] = React.useState<`${Booleanish}`>(isOpenAside as `${Booleanish}`);
const { dir: _dir, ..._direction } = useDirection({ initialDirection: dir as Direction });
return { theme, dir: _dir, openAside, setOpenAside, ..._direction, ...others };
Expand All @@ -52,7 +48,7 @@ function useAppFuntions(_app: useAppProps) {
export function AppProvider({ children, ...props }: AppProviderProps) {
const { theme, ...app } = useAppFuntions({ ...props });

const value = { useCookies, theme: theme as Theme, ...app };
const value = { theme: theme as Theme, ...app };
return (
<ctx.Provider {...{ value }}>
<html lang="en" dir={app.dir} suppressHydrationWarning>
Expand Down
14 changes: 5 additions & 9 deletions ui/config/cookies.ts → ui/config/cookies-client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"use cilent";
import { Cookies } from "./types";
import * as React from "react";

export type CookiesName = `${Cookies}` | (string & {});
import { CookiesName } from "./app-context";

export function setCookies(name: CookiesName, value: string, days = 30) {
const date = new Date();
Expand All @@ -12,12 +10,10 @@ export function setCookies(name: CookiesName, value: string, days = 30) {

export function useCookies<T extends string>(name: CookiesName, initial: T) {
const getCookie = React.useCallback(() => {
const cookies =
typeof document !== "undefined" &&
document.cookie
.split("; ")
.find(row => row.startsWith(`${name}=`))
?.split("=")[1];
const cookies = document.cookie
.split("; ")
.find(row => row.startsWith(`${name}=`))
?.split("=")[1];
return cookies ? decodeURIComponent(cookies) : initial;
}, [name, initial]);

Expand Down
24 changes: 24 additions & 0 deletions ui/config/cookies-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use server";
import { cookies } from "next/headers";
import { Cookies } from "./types";

export async function setCookies(name: string, value: string) {
(await cookies()).set({
name,
value,
secure: true,
httpOnly: true,
path: "/",
sameSite: "strict",
maxAge: 60 * 60 * 24 * 365 // Cookie values ​​are valid for one year
});
}

export async function cookiesValues() {
const cookieStore = await cookies();
const dir = cookieStore.get(Cookies.dir)?.value;
const theme = cookieStore.get(Cookies.theme)?.value;
const isOpenAside = cookieStore.get(Cookies.isOpenAside)?.value;

return { dir, theme, isOpenAside };
}
Loading

0 comments on commit 6fb73df

Please sign in to comment.