Resolve rejected Apple:
Add:
public/aset/logo/hiconnect.png
src/app/(support)/
src/app/api/helper/
Fix:
- bun.lock
- package.json
- src/app/api/auth/login/route.ts
- src/app/api/auth/resend/route.ts
- src/middleware.tsx
### No issue
This commit is contained in:
133
src/app/(support)/delete-account/page.tsx
Normal file
133
src/app/(support)/delete-account/page.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Grid,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import Image from "next/image";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function DeleteAccount() {
|
||||
const [phoneNumber, setPhoneNumber] = useState<string>("");
|
||||
const [data, setData] = useState({
|
||||
description: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// Hanya di client, setelah mount
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const phone = urlParams.get("phone");
|
||||
if (phone) {
|
||||
setPhoneNumber(phone);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handlerSubmit = async () => {
|
||||
if (!phoneNumber || !data.description) {
|
||||
return notifications.show({
|
||||
title: "Error",
|
||||
message: "Please fill in description & phone number",
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/helper/delete-account", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
number: phoneNumber,
|
||||
description: data.description,
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
notifications.show({
|
||||
title: "Success",
|
||||
message: "Account will process to delete",
|
||||
color: "green",
|
||||
});
|
||||
|
||||
setData({
|
||||
description: "",
|
||||
});
|
||||
}
|
||||
|
||||
if (!result.success) {
|
||||
notifications.show({
|
||||
title: "Error",
|
||||
message: result.error,
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
backgroundColor: "#f5f5f5",
|
||||
padding: "20px",
|
||||
}}
|
||||
>
|
||||
<Paper withBorder shadow="md" p={"lg"}>
|
||||
<Stack align="center">
|
||||
<Image
|
||||
src="/aset/logo/hiconnect.png"
|
||||
alt="logo"
|
||||
width={100}
|
||||
height={100}
|
||||
/>
|
||||
<Title>Delete Account</Title>
|
||||
<Stack spacing={0} align="center">
|
||||
<Text align="center" fw={"lighter"}>
|
||||
To delete your account with phone number{" "}
|
||||
{phoneNumber ? `+${phoneNumber}` : ""}.
|
||||
</Text>
|
||||
<Text align="center" fw={"lighter"}>
|
||||
Type your message with subject ‘Delete Account’
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
<Grid w={"100%"}>
|
||||
<Grid.Col span={8}>
|
||||
<TextInput
|
||||
value={data.description}
|
||||
w={"100%"}
|
||||
placeholder="Type your subject here"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
description: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4}>
|
||||
<Button onClick={handlerSubmit} w={"100%"}>
|
||||
Submit
|
||||
</Button>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
189
src/app/(support)/support-center/page.tsx
Normal file
189
src/app/(support)/support-center/page.tsx
Normal file
@@ -0,0 +1,189 @@
|
||||
"use client";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
Textarea,
|
||||
TextInput,
|
||||
Title
|
||||
} from "@mantine/core";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { IconBrandGmail, IconLocation } from "@tabler/icons-react";
|
||||
import Image from "next/image";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function SupportCenter() {
|
||||
const [data, setData] = useState({
|
||||
email: "",
|
||||
title: "",
|
||||
description: "",
|
||||
});
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!data.email || !data.title || !data.description) {
|
||||
return notifications.show({
|
||||
title: "Error",
|
||||
color: "red",
|
||||
message: "Please fill in all fields.",
|
||||
});
|
||||
}
|
||||
|
||||
const response = await fetch("/api/helper/support-center", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
notifications.show({
|
||||
title: "Success",
|
||||
color: "green",
|
||||
message: "Message sent successfully.",
|
||||
});
|
||||
|
||||
setData({
|
||||
email: "",
|
||||
title: "",
|
||||
description: "",
|
||||
});
|
||||
}
|
||||
|
||||
if (!result.success) {
|
||||
notifications.show({
|
||||
title: "Error",
|
||||
color: "red",
|
||||
message: result.error,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100vh",
|
||||
backgroundColor: "#f5f5f5",
|
||||
padding: "20px",
|
||||
}}
|
||||
>
|
||||
<Stack spacing={"lg"}>
|
||||
<Stack align="center">
|
||||
<Stack spacing={"xs"} align="center">
|
||||
<Group>
|
||||
<Image
|
||||
src="/aset/logo/hiconnect.png"
|
||||
alt="logo"
|
||||
width={50}
|
||||
height={50}
|
||||
/>
|
||||
|
||||
<Title>Support Center</Title>
|
||||
</Group>
|
||||
<Text align="center">
|
||||
Send us a message and we'll get back to you as soon as possible.
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Paper style={{ padding: "20px" }} withBorder shadow="md">
|
||||
<SimpleGrid
|
||||
cols={2}
|
||||
// verticalSpacing={50}
|
||||
spacing={50}
|
||||
breakpoints={[
|
||||
{ maxWidth: "md", cols: 2, spacing: "md" },
|
||||
{ maxWidth: "sm", cols: 2, spacing: "sm" },
|
||||
{ maxWidth: "xs", cols: 1, spacing: "sm" },
|
||||
]}
|
||||
>
|
||||
<Stack>
|
||||
<Stack spacing={0}>
|
||||
<Title order={2}>Contact Information</Title>
|
||||
<Text>For general inquiries, please contact us !</Text>
|
||||
</Stack>
|
||||
<Group>
|
||||
<IconBrandGmail
|
||||
size={40}
|
||||
style={{
|
||||
backgroundColor: "gray",
|
||||
borderRadius: "10%",
|
||||
padding: "5px",
|
||||
}}
|
||||
/>
|
||||
<Stack spacing={0}>
|
||||
<Text fw={"bold"}>Email</Text>
|
||||
<Text>bip.baliinteraktifperkasa@gmail.com</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<IconLocation
|
||||
size={40}
|
||||
style={{
|
||||
backgroundColor: "gray",
|
||||
borderRadius: "10%",
|
||||
padding: "5px",
|
||||
}}
|
||||
/>
|
||||
<Stack spacing={0}>
|
||||
<Text fw={"bold"}>Location</Text>
|
||||
<Text>Bali, Indonesia</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<Title order={2}>Send a Message</Title>
|
||||
|
||||
<TextInput
|
||||
label="Email"
|
||||
placeholder="Email"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
email: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Title"
|
||||
placeholder="Title"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
title: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label="Description"
|
||||
placeholder="Description"
|
||||
onChange={(e) => {
|
||||
setData({
|
||||
...data,
|
||||
description: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button color="yellow" onClick={() => handleSubmit()}>
|
||||
Submit
|
||||
</Button>
|
||||
</Stack>
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -29,11 +29,11 @@ export async function POST(req: Request) {
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n>> Kode OTP anda: ${codeOtp}.`;
|
||||
const encodedMsg = encodeURIComponent(msg);
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%5Cn%5Cn%3E%3E%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
// const encodedMsg = encodeURIComponent(msg);
|
||||
|
||||
const res = await fetch(
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=${encodedMsg}`,
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
|
||||
@@ -16,11 +16,10 @@ export async function POST(req: Request) {
|
||||
const body = await req.json();
|
||||
const { nomor } = body;
|
||||
|
||||
const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n>> Kode OTP anda: ${codeOtp}.`;
|
||||
const encodedMsg = encodeURIComponent(msg);
|
||||
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%5Cn%5Cn%3E%3E%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||
|
||||
const res = await fetch(
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=${encodedMsg}`,
|
||||
`https://wa.wibudev.com/code?nom=${nomor}&text=${msg}`,
|
||||
{ cache: "no-cache" }
|
||||
);
|
||||
|
||||
|
||||
41
src/app/api/helper/delete-account/route.ts
Normal file
41
src/app/api/helper/delete-account/route.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { Resend } from "resend";
|
||||
|
||||
const resend = new Resend(process.env.RESEND_APIKEY);
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const body = await req.json();
|
||||
|
||||
try {
|
||||
const { number } = body;
|
||||
|
||||
if (!number) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Missing required fields.",
|
||||
});
|
||||
}
|
||||
|
||||
const data = await resend.emails.send({
|
||||
from: `+${number} <onboarding@resend.dev>`,
|
||||
to: ["bagasbanuna02@gmail.com"], // ganti sesuai email kamu
|
||||
// cc: ["bip.baliinteraktifperkasa@gmail.com"],
|
||||
subject: "Delete Account",
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; font-size: 16px; color: #333;">
|
||||
<h3>New Message to Delete Account</h3>
|
||||
<p><strong>User with phone number +${number}</strong></p>
|
||||
<p><strong>Description: Want to delete account !!</strong></p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true, data });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
41
src/app/api/helper/support-center/route.ts
Normal file
41
src/app/api/helper/support-center/route.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { Resend } from "resend";
|
||||
|
||||
const resend = new Resend(process.env.RESEND_APIKEY);
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const body = await req.json();
|
||||
|
||||
try {
|
||||
const { email, title, description } = body;
|
||||
|
||||
if (!email || !title || !description) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Missing required fields.",
|
||||
});
|
||||
}
|
||||
|
||||
const data = await resend.emails.send({
|
||||
from: `${email} <onboarding@resend.dev>`,
|
||||
to: ["bip.baliinteraktifperkasa@gmail.com"], // ganti sesuai email kamu
|
||||
subject: title,
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; font-size: 16px; color: #333;">
|
||||
<h3>New Message Received</h3>
|
||||
<p><strong>Email:</strong> ${email}</p>
|
||||
<p><strong>Title:</strong> ${title}</p>
|
||||
<p><strong>Description:</strong><br/>${description.replace(/\n/g, "<br/>")}</p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true, data });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: (error as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user