diff --git a/app/components/icons/close.tsx b/app/components/icons/close.tsx new file mode 100644 index 0000000..4c56409 --- /dev/null +++ b/app/components/icons/close.tsx @@ -0,0 +1,23 @@ +import type { JSX, SVGProps } from 'react' + +export const CloseIcon = ( + properties: JSX.IntrinsicAttributes & SVGProps, +) => { + return ( + + + + ) +} diff --git a/app/components/icons/eye.tsx b/app/components/icons/eye.tsx new file mode 100644 index 0000000..73cd4b8 --- /dev/null +++ b/app/components/icons/eye.tsx @@ -0,0 +1,21 @@ +import type { JSX, SVGProps } from 'react' + +export const EyeIcon = ( + properties: JSX.IntrinsicAttributes & SVGProps, +) => { + return ( + + + + ) +} diff --git a/app/components/icons/menu.tsx b/app/components/icons/menu.tsx new file mode 100644 index 0000000..14bfd62 --- /dev/null +++ b/app/components/icons/menu.tsx @@ -0,0 +1,21 @@ +import type { JSX, SVGProps } from 'react' + +export const MenuIcon = ( + properties: JSX.IntrinsicAttributes & SVGProps, +) => { + return ( + + + + ) +} diff --git a/app/components/popup/header-modal.tsx b/app/components/popup/header-modal.tsx new file mode 100644 index 0000000..cc1f38f --- /dev/null +++ b/app/components/popup/header-modal.tsx @@ -0,0 +1,44 @@ +import type { ReactNode } from 'react' +import { Link } from 'react-router' + +import { LeftArrow } from '~/components/icons/left-arrow' +import { APP } from '~/data/meta' + +type THeaderModal = { + typeForm?: string + titleForm?: string + children: ReactNode +} +export default function HeaderModal({ typeForm, children }: THeaderModal) { + return ( + <> +
+ + + +
+
+
+ + {APP.title} + +
+ +
+ {children} +

{typeForm}

+
+
+ + ) +} diff --git a/app/components/popup/modal.tsx b/app/components/popup/modal.tsx index c072f5b..c30ae76 100644 --- a/app/components/popup/modal.tsx +++ b/app/components/popup/modal.tsx @@ -1,7 +1,7 @@ import { Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react' import type { ReactNode } from 'react' -interface ModalProperties { +type ModalProperties = { isOpen: boolean onClose: () => void children: ReactNode diff --git a/app/components/popup/succes-payment.tsx b/app/components/popup/succes-payment.tsx index 9690ab4..00a0b9d 100644 --- a/app/components/popup/succes-payment.tsx +++ b/app/components/popup/succes-payment.tsx @@ -1,48 +1,29 @@ -import { Link } from 'react-router' +import { Button } from '@headlessui/react' -import { LeftArrow } from '~/components/icons/left-arrow' +import HeaderModal from '~/components/popup/header-modal' import { APP } from '~/data/meta' export default function PopupSuccessPayment() { return ( -
-
-
- - - -
- -
- - {APP.title} - -
+ <> +
+ +

Selamat! Pembayaran anda berhasil!

+
-

Selamat! Pembayaran anda berhasil!

-
+
{APP.title}
- +
-
+ ) } diff --git a/app/components/popup/succes-register.tsx b/app/components/popup/succes-register.tsx index 7f96a37..284ee81 100644 --- a/app/components/popup/succes-register.tsx +++ b/app/components/popup/succes-register.tsx @@ -1,3 +1,4 @@ +import { Button } from '@headlessui/react' import { Link } from 'react-router' import { LeftArrow } from '~/components/icons/left-arrow' @@ -38,9 +39,9 @@ export default function PopupSuccesRegister() { className="h-[350px]" />
- +
diff --git a/app/components/popup/succes-reset-pass.tsx b/app/components/popup/succes-reset-pass.tsx index 4bf8627..8808d01 100644 --- a/app/components/popup/succes-reset-pass.tsx +++ b/app/components/popup/succes-reset-pass.tsx @@ -1,3 +1,4 @@ +import { Button } from '@headlessui/react' import { Link } from 'react-router' import { LeftArrow } from '~/components/icons/left-arrow' @@ -40,9 +41,9 @@ export default function PopupSuccessResetPass() { className="h-[350px]" /> - + diff --git a/app/components/ui/banner.tsx b/app/components/ui/banner.tsx index 02396f0..f126dd1 100644 --- a/app/components/ui/banner.tsx +++ b/app/components/ui/banner.tsx @@ -11,7 +11,7 @@ export default function Banner() { className="mt-2 h-full py-2" > {APP.title} diff --git a/app/components/ui/form-forgot-password.tsx b/app/components/ui/form-forgot-password.tsx index f7aa7d4..ec0ac89 100644 --- a/app/components/ui/form-forgot-password.tsx +++ b/app/components/ui/form-forgot-password.tsx @@ -1,40 +1,14 @@ -import { Link } from 'react-router' - -import { LeftArrow } from '~/components/icons/left-arrow' -import { APP } from '~/data/meta' +import HeaderModal from '~/components/popup/header-modal' +import { Button } from '~/components/ui/button' export default function FormForgotPassword() { return ( -
-
-
- - - -
- -
- - {APP.title} - -
- -
-

- Selamat Datang, silakan isi keterangan akun Anda untuk melanjutkan! -

-
+
+ +

Selamat Datang, silakan masukkan akun Anda untuk melanjutkan!

+
+
{/* Input Email / No Telepon */}
@@ -53,9 +27,9 @@ export default function FormForgotPassword() {
{/* Tombol Masuk */} - +
diff --git a/app/components/ui/form-login.tsx b/app/components/ui/form-login.tsx index d8379d2..732e53c 100644 --- a/app/components/ui/form-login.tsx +++ b/app/components/ui/form-login.tsx @@ -1,7 +1,9 @@ // import { EyeIcon, EyeOffIcon } from 'lucide-react' +import { Button } from '@headlessui/react' import { useState } from 'react' import { Link } from 'react-router' +import { EyeIcon } from '~/components/icons/eye' import { APP } from '~/data/meta' const FormLogin = () => { @@ -60,7 +62,17 @@ const FormLogin = () => { className="absolute top-9 right-3 text-gray-500" onClick={() => setShowPassword(!showPassword)} > - {/* {showPassword ? : } */} + {showPassword ? ( + + ) : ( + + )}
@@ -76,9 +88,9 @@ const FormLogin = () => {
{/* Tombol Masuk */} - + {/* Link Daftar */} diff --git a/app/components/ui/form-register .tsx b/app/components/ui/form-register .tsx index 726c0fd..f7c1dcd 100644 --- a/app/components/ui/form-register .tsx +++ b/app/components/ui/form-register .tsx @@ -1,43 +1,17 @@ -// import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useState } from 'react' -import { Link } from 'react-router' -import { LeftArrow } from '~/components/icons/left-arrow' -import { APP } from '~/data/meta' +import HeaderModal from '~/components/popup/header-modal' +import { Button } from '~/components/ui/button' export default function FormRegister() { const [showPassword, setShowPassword] = useState(false) return ( -
-
-
- - - -
- -
- - {APP.title} - -
- -
-

- Selamat Datang, silakan isi keterangan akun Anda untuk melanjutkan! -

-
+
+ +

Selamat Datang, silakan masukkan data Anda untuk melanjutkan!

+
+
{/* Input Email / No Telepon */}
@@ -131,9 +105,9 @@ export default function FormRegister() {
{/* Tombol Masuk */} - +
diff --git a/app/components/ui/form-subscription.tsx b/app/components/ui/form-subscription.tsx index 7374bb6..4af05ee 100644 --- a/app/components/ui/form-subscription.tsx +++ b/app/components/ui/form-subscription.tsx @@ -1,41 +1,17 @@ -import React from 'react' -import { Link } from 'react-router' +import { Button } from '@headlessui/react' -import { LeftArrow } from '~/components/icons/left-arrow' -import { APP } from '~/data/meta' +import HeaderModal from '~/components/popup/header-modal' export default function FormSubscription() { return ( -
-
-
- - - -
- -
- - {APP.title} - -
- -
-

- Selamat Datang, silakan Pilih Subscription Anda untuk melanjutkan! -

-
+
+ +

+ Selamat Datang, silakan Pilih Subscription Anda untuk melanjutkan! +

+
+
{/* Subscribe*/}
@@ -51,9 +27,9 @@ export default function FormSubscription() {
{/* Tombol Masuk */} - +
diff --git a/app/layouts/header-menu-mobile.tsx b/app/layouts/header-menu-mobile.tsx index 4d9c535..def919b 100644 --- a/app/layouts/header-menu-mobile.tsx +++ b/app/layouts/header-menu-mobile.tsx @@ -1,6 +1,8 @@ import { useState } from 'react' import { Link } from 'react-router' +import { CloseIcon } from '~/components/icons/close' +import { MenuIcon } from '~/components/icons/menu' import { HeaderSearch } from '~/layouts/header-search' import { MENU } from './menu' @@ -13,31 +15,27 @@ export default function HeaderMenuMobile() { } return ( <> -
+
{/* Menu */}
{/* Tombol Close */} {/* List Menu */} -
    +
      {MENU.map((item, index) => (
    • - - - +
      diff --git a/app/pages/news-detail/index.tsx b/app/pages/news-detail/index.tsx index 0b57c33..988c04b 100644 --- a/app/pages/news-detail/index.tsx +++ b/app/pages/news-detail/index.tsx @@ -41,12 +41,15 @@ export const NewsDetailPage = () => { className="object-center" />
      -
      {content}
      +

      Share this post

      - +
      {tags?.map((tag) => ( diff --git a/app/root.tsx b/app/root.tsx index 99ad302..294e404 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -43,10 +43,6 @@ export function Layout({ children }: { children: React.ReactNode }) { return ( - = 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -1975,6 +1991,14 @@ packages: resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.0: + resolution: {integrity: sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -2397,10 +2421,25 @@ packages: resolution: {integrity: sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + html-dom-parser@5.0.13: + resolution: {integrity: sha512-B7JonBuAfG32I7fDouUQEogBrz3jK9gAuN1r1AaXpED6dIhtg/JwiSRhjGL7aOJwRz3HU4efowCjQBaoXiREqg==} + + html-react-parser@5.2.2: + resolution: {integrity: sha512-yA5012CJGSFWYZsgYzfr6HXJgDap38/AEP4ra8Cw+WHIi2ZRDXRX/QVYdumRf1P8zKyScKd6YOrWYvVEiPfGKg==} + peerDependencies: + '@types/react': 0.14 || 15 || 16 || 17 || 18 || 19 + react: 0.14 || 15 || 16 || 17 || 18 || 19 + peerDependenciesMeta: + '@types/react': + optional: true + html@1.0.0: resolution: {integrity: sha512-lw/7YsdKiP3kk5PnR1INY17iJuzdAtJewxr14ozKJWbbR97znovZ0mh+WEMZ8rjc3lgTK+ID/htTjuyGKB52Kw==} hasBin: true + htmlparser2@10.0.0: + resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -2451,6 +2490,9 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -3343,6 +3385,9 @@ packages: react-lifecycles-compat@3.0.4: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} + react-property@2.0.2: + resolution: {integrity: sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==} + react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} @@ -3701,6 +3746,12 @@ packages: resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==} engines: {node: '>=14.16'} + style-to-js@1.1.16: + resolution: {integrity: sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==} + + style-to-object@1.0.8: + resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} + stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} @@ -5910,6 +5961,24 @@ snapshots: dependencies: '@babel/runtime': 7.26.7 + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 @@ -5965,6 +6034,10 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + entities@4.5.0: {} + + entities@6.0.0: {} + env-paths@2.2.1: {} environment@1.1.0: {} @@ -6567,10 +6640,32 @@ snapshots: dependencies: lru-cache: 7.18.3 + html-dom-parser@5.0.13: + dependencies: + domhandler: 5.0.3 + htmlparser2: 10.0.0 + + html-react-parser@5.2.2(@types/react@19.0.8)(react@19.0.0): + dependencies: + domhandler: 5.0.3 + html-dom-parser: 5.0.13 + react: 19.0.0 + react-property: 2.0.2 + style-to-js: 1.1.16 + optionalDependencies: + '@types/react': 19.0.8 + html@1.0.0: dependencies: concat-stream: 1.6.2 + htmlparser2@10.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 6.0.0 + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -6611,6 +6706,8 @@ snapshots: ini@4.1.1: {} + inline-style-parser@0.2.4: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -7394,6 +7491,8 @@ snapshots: react-lifecycles-compat@3.0.4: {} + react-property@2.0.2: {} + react-refresh@0.14.2: {} react-remove-scroll-bar@2.3.8(@types/react@19.0.8)(react@19.0.0): @@ -7827,6 +7926,14 @@ snapshots: strip-json-comments@5.0.1: {} + style-to-js@1.1.16: + dependencies: + style-to-object: 1.0.8 + + style-to-object@1.0.8: + dependencies: + inline-style-parser: 0.2.4 + stylis@4.2.0: {} summary@2.1.0: {}