2 Commits

Author SHA1 Message Date
Kar
ead0b8aeda Release 0.0.1 (PR #4) from master into release
Reviewed-on: #4
2025-03-20 15:27:05 +00:00
Kar
0900d51954 Merge pull request 'pull footer improvement to the stage' (#3) from staging into master
Reviewed-on: #3
2025-03-20 15:25:07 +00:00
14 changed files with 75 additions and 322 deletions

2
.gitignore vendored
View File

@@ -5,7 +5,7 @@ dist/
# dependencies # dependencies
node_modules/ node_modules/
public/host-api/
# logs # logs
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*

View File

@@ -1,14 +0,0 @@
### git flow guide / protocol
# dev - any one is free to create / push to / any experiment on this branch
# staging - it is the stage for all developer. all branchout and push over here.
*start point / fork point is staging, i.e. any fix/feature/improvement - you must start branching out from staging.
*better to name your branch with 'z-' , i.e. z-layout-footer-improvement (z-: identifier for temporary and safe to remove from the central repo -> then the file identifier -> then short info regarding the intent)
*many developers prefer feat/feature_name, i faced issue managing those branch using cli (bsd even alpine) for the slash(/)
## staging must have a automated test and deploy mechanism, so that developers can can always be on the same page regarding build/merge conflict issue
# test - staging to test by tester
# master - test to master by tester after full test
# release - master to release with version tag
final packaging and release

BIN
dist.zip

Binary file not shown.

View File

@@ -6,8 +6,7 @@
"dev": "astro dev", "dev": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro", "astro": "astro"
"push-s33": "rsync -rv --exclude .hta_config/conf.php dist/ dev2@siliconpin.s33.siliconpin.com:/home/dev2/domains/siliconpin.s33.siliconpin.com/public_html/"
}, },
"dependencies": { "dependencies": {
"@astrojs/react": "^4.2.1", "@astrojs/react": "^4.2.1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

View File

@@ -1,48 +0,0 @@
TLDR;
=====================================================
Nirvana License, i.e. Beings needs no license
=====================================================
Preamble
------------
GNU, MIT, APACHE, Opensource, Source available -
So many options, why a new one?
To add / remove confusion may be, or
Just to remind Humans, you have evolved to as
being, you don't need one. Having license is like
having limitation, boundation not freedom, You
can have a Driving license and drive irresponsibly,
license provider / authority can impose some
nonsense rules. No matter how hard we try, Beings
don't like to be bound, limited...
They want freedom... little more - Nirvana.
-----------------------------------------------------
Experience
------------
Best of the best GPL(copyleft) and it's derivatives
are confusing which one to choose & its protected
by copyright laws, but i get the idea of 4 freedoms.
Developers don't want to deal with lawyers (seems
wasting years), we want to build something.
I have seen license violation a lot, as they have
a fleet of lawyers.
I have seen Open Source is being used a suppressor
to GNU,GPL -Freedom centric ones. Going against the
ideology of creator of the open source definition
Bruce Perens, Eric S. Raymond,
-----------------------------------------------------
Quote
--------
Every rule / law has an exception except this.
Beings do not need a license, enough to have sense.
- Suvankar Sarkar (AKA Kar)
-----------------------------------------------------
=====================================================
Mentioned some licenses above good to bad, there may be
some reason to use any existing license.
you are free to choose this one, defined below.
.....................................................

View File

@@ -30,8 +30,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
const [dnsVerified, setDnsVerified] = useState({ const [dnsVerified, setDnsVerified] = useState({
cname: false, cname: false,
ns: false, ns: false,
a: false, a: false
ip: false
}); });
// Form validation // Form validation
@@ -62,7 +61,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
} }
validateForm(); validateForm();
}, [useCustomDomain, dnsVerified.cname, dnsVerified.ns, dnsVerified.ns, domainType, dnsMethod]); }, [useCustomDomain, dnsVerified.cname, dnsVerified.ns, domainType, dnsMethod]);
// Show toast notification // Show toast notification
const showToast = (message) => { const showToast = (message) => {
@@ -111,8 +110,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
setDnsVerified({ setDnsVerified({
cname: false, cname: false,
ns: false, ns: false,
a: false, a: false
ip: false
}); });
} else { } else {
// Force SiliconPin subdomain to be checked if custom domain is checked // Force SiliconPin subdomain to be checked if custom domain is checked
@@ -248,10 +246,6 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
setFormValid(false); setFormValid(false);
return; return;
} }
if (dnsMethod === 'ip' && !dnsVerified.ip) {
setFormValid(false);
return;
}
} }
setFormValid(true); setFormValid(true);
@@ -267,7 +261,20 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
} }
// In a real app, this would submit the form data to the server // In a real app, this would submit the form data to the server
console.log([{ deploymentType, appType, sampleWebAppType, sourceType, repoUrl, deploymentKey, useSubdomain, useCustomDomain, customDomain, customSubdomain, domainType, dnsMethod}]); console.log({
deploymentType,
appType,
sampleWebAppType,
sourceType,
repoUrl,
deploymentKey,
useSubdomain,
useCustomDomain,
customDomain,
customSubdomain,
domainType,
dnsMethod
});
showToast('Form submitted successfully!'); showToast('Form submitted successfully!');
}; };
@@ -543,10 +550,9 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
{/* Domain Validation */} {/* Domain Validation */}
<button <button
disabled={!customDomain}
type="button" type="button"
onClick={validateDomain} onClick={validateDomain}
className={`px-4 py-2 ${!customDomain ? 'bg-neutral-600 cursor-not-allowed' : 'bg-[#6d9e37] focus:ring-[#6d9e37] transition-colors'} text-white font-medium rounded-md transition-colors focus:outline-none`} className="px-4 py-2 bg-neutral-600 text-white font-medium rounded-md hover:bg-neutral-500 transition-colors focus:outline-none focus:ring-2 focus:ring-neutral-500"
> >
Validate Domain Validate Domain
</button> </button>
@@ -576,7 +582,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
{/* CNAME Record Option */} {/* CNAME Record Option */}
<div className="p-4 bg-neutral-700/30 rounded-md border border-neutral-600 space-y-3"> <div className="p-4 bg-neutral-700/30 rounded-md border border-neutral-600 space-y-3">
<label for="dns-cname" className="flex items-start cursor-pointer"> <div className="flex items-start">
<input <input
type="radio" type="radio"
id="dns-cname" id="dns-cname"
@@ -616,114 +622,67 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
</button> </button>
</div> </div>
</div> </div>
</label> </div>
</div> </div>
{/* Nameserver Option (only for full domains, not subdomains) */} {/* Nameserver Option (only for full domains, not subdomains) */}
{domainType === 'domain' && ( {domainType === 'domain' && (
<> <div className="p-4 bg-neutral-700/30 rounded-md border border-neutral-600 space-y-3">
<div className="p-4 bg-neutral-700/30 rounded-md border border-neutral-600 space-y-3"> <div className="flex items-start">
<label for="dns-ns" className="flex items-start cursor-pointer"> <input
<input type="radio"
type="radio" id="dns-ns"
id="dns-ns" name="dns-method"
name="dns-method" value="ns"
value="ns" checked={dnsMethod === 'ns'}
checked={dnsMethod === 'ns'} onChange={handleDnsMethodChange}
onChange={handleDnsMethodChange} className="mt-1 mr-2"
className="mt-1 mr-2" />
/> <div className="flex-1">
<div className="flex-1"> <label htmlFor="dns-ns" className="block text-white font-medium">Use Our Nameservers</label>
<label htmlFor="dns-ns" className="block text-white font-medium">Use Our Nameservers</label> <p className="text-sm text-neutral-300">Update your domain's nameservers to use ours</p>
<p className="text-sm text-neutral-300">Update your domain's nameservers to use ours</p>
<div className="mt-3 space-y-2"> <div className="mt-3 space-y-2">
<div className="flex items-center"> <div className="flex items-center">
<div className="bg-neutral-800 p-2 rounded font-mono text-sm text-neutral-300">ns1.siliconpin.com</div> <div className="bg-neutral-800 p-2 rounded font-mono text-sm text-neutral-300">ns1.siliconpin.com</div>
<button
type="button"
onClick={() => copyToClipboard('ns1.siliconpin.com')}
className="ml-2 text-[#6d9e37] hover:text-white"
aria-label="Copy nameserver value"
>
<span className="text-lg">📋</span>
</button>
</div>
<div className="flex items-center">
<div className="bg-neutral-800 p-2 rounded font-mono text-sm text-neutral-300">ns2.siliconpin.com</div>
<button
type="button"
onClick={() => copyToClipboard('ns2.siliconpin.com')}
className="ml-2 text-[#6d9e37] hover:text-white"
aria-label="Copy nameserver value"
>
<span className="text-lg">📋</span>
</button>
</div>
</div>
<div className="mt-2 text-right">
<button <button
type="button" type="button"
onClick={() => checkDnsConfig('ns')} onClick={() => copyToClipboard('ns1.siliconpin.com')}
className={`px-3 py-1 text-white text-sm rounded className="ml-2 text-[#6d9e37] hover:text-white"
${dnsVerified.ns aria-label="Copy nameserver value"
? 'bg-green-700 hover:bg-green-600'
: 'bg-neutral-600 hover:bg-neutral-500'}`}
> >
{dnsVerified.ns ? '✓ Nameservers Verified' : 'Check Nameservers'} <span className="text-lg">📋</span>
</button>
</div>
<div className="flex items-center">
<div className="bg-neutral-800 p-2 rounded font-mono text-sm text-neutral-300">ns2.siliconpin.com</div>
<button
type="button"
onClick={() => copyToClipboard('ns2.siliconpin.com')}
className="ml-2 text-[#6d9e37] hover:text-white"
aria-label="Copy nameserver value"
>
<span className="text-lg">📋</span>
</button> </button>
</div> </div>
</div> </div>
</label>
</div>
<div className="p-4 bg-neutral-700/30 rounded-md border border-neutral-600 space-y-3"> <div className="mt-2 text-right">
<label for="dns-ip" className="flex items-start cursor-pointer"> <button
<input type="button"
type="radio" onClick={() => checkDnsConfig('ns')}
id="dns-ip" className={`px-3 py-1 text-white text-sm rounded
name="dns-method" ${dnsVerified.ns
value="ip" ? 'bg-green-700 hover:bg-green-600'
checked={dnsMethod === 'ip'} : 'bg-neutral-600 hover:bg-neutral-500'}`}
onChange={handleDnsMethodChange} >
className="mt-1 mr-2" {dnsVerified.ns ? '✓ Nameservers Verified' : 'Check Nameservers'}
/> </button>
<div className="flex-1">
<label htmlFor="dns-ip" className="block text-white font-medium">Use Our IP Address</label>
<p className="text-sm text-neutral-300">Update your domain's nameservers to use ours</p>
<div className="mt-3 space-y-2">
<div className="flex items-center">
<div className="bg-neutral-800 p-2 rounded font-mono text-sm text-neutral-300">xxx.xxx.x.xx</div>
<button
type="button"
onClick={() => copyToClipboard('xxx.xxx.x.xx')}
className="ml-2 text-[#6d9e37] hover:text-white"
aria-label="Copy nameserver value"
>
<span className="text-lg">📋</span>
</button>
</div>
</div>
<div className="mt-2 text-right">
<button
type="button"
onClick={() => checkDnsConfig('ip')}
className={`px-3 py-1 text-white text-sm rounded
${dnsMethod === 'ip'
? 'bg-green-700 hover:bg-green-600'
: 'bg-neutral-600 hover:bg-neutral-500'}`}
>
{/* {dnsVerified.ip ? ' IP Address Verified' : 'Check IP Address'} */}
Proceed to Pay
</button>
</div>
</div> </div>
</label> </div>
</div> </div>
</> </div>
)} )}
</div> </div>
)} )}
@@ -733,6 +692,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
</div> </div>
</div> </div>
</div> </div>
{/* Form Submit Button */} {/* Form Submit Button */}
<button <button
type="submit" type="submit"
@@ -746,6 +706,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
Start the Deployment Start the Deployment
</button> </button>
</form> </form>
<Toast visible={toast.visible} message={toast.message} /> <Toast visible={toast.visible} message={toast.message} />
</div> </div>
); );

View File

@@ -133,7 +133,7 @@ const contactSchema = {
<span class="text-neutral-300 font-medium">Sunday:</span> <span class="text-neutral-300 font-medium">Sunday:</span>
<span class="text-white">Closed</span> <span class="text-white">Closed</span>
</div> </div>
<div class="pt-3 border-t border-neutral-700 flex items-center justify-between"> <div class="pt-3 border-t border-neutral-700">
<span class="text-neutral-300">Technical Support:</span> <span class="text-neutral-300">Technical Support:</span>
<span class="text-[#6d9e37] font-semibold block mt-1">24/7</span> <span class="text-[#6d9e37] font-semibold block mt-1">24/7</span>
</div> </div>

View File

@@ -1,27 +0,0 @@
---
import Layout from "../../layouts/Layout.astro"
---
<Layout title="">
<div>
<pre id="get-response">Adding domain, please wait...</pre>
</div>
<script is:inline>
fetch('/host-api/add-domain/')
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json();
})
.then(data => {
const resultElement = document.getElementById('get-response');
if (data.status === 'success') {
resultElement.textContent = `✅ ${data.message}\n${data.output || ''}`;
} else {
resultElement.textContent = `❌ ${data.message}`;
}
})
.catch(error => {
document.getElementById('get-response').textContent = `❌ Fetch Error: ${error.message}`;
});
</script>
</Layout>

View File

@@ -1,45 +0,0 @@
---
import Layout from "../../layouts/Layout.astro"
---
<Layout title="">
<div>
<h2>Delete Domain</h2>
<form id="deleteDomainForm">
<input type="text" id="domainName" placeholder="example.com" required>
<button type="submit">Delete Domain</button>
</form>
<pre id="deleteResponse"></pre>
</div>
<script is:inline>
document.getElementById('deleteDomainForm').addEventListener('submit', async (e) => {
e.preventDefault();
const domain = document.getElementById('domainName').value;
const responseElement = document.getElementById('deleteResponse');
responseElement.textContent = "Deleting domain...";
try {
const response = await fetch('/host-api/delete-domain/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `domain=${encodeURIComponent(domain)}`
});
const data = await response.json();
if (data.status === 'success') {
responseElement.textContent = `✅ ${data.message}\nDomain: ${data.domain}`;
// Refresh domain list if needed
setTimeout(() => window.location.reload(), 1500);
} else {
responseElement.textContent = `❌ ${data.message}\nError: ${data.error || 'Unknown error'}`;
}
} catch (error) {
responseElement.textContent = `❌ Network Error: ${error.message}`;
}
});
</script>
</Layout>

View File

@@ -1,40 +0,0 @@
---
import Layout from "../../layouts/Layout.astro"
---
<Layout title="">
<div>
<pre id="get-response">Loading domains...</pre>
</div>
<script is:inline>
fetch('/host-api/list-domain/')
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json();
})
.then(data => {
const pre = document.getElementById('get-response');
if (data.status === 'success') {
// Format domains as a table
let output = 'DOMAINS LIST:\n\n';
output += 'Domain'.padEnd(40) + 'IP'.padEnd(15) + 'SSL'.padEnd(5) + 'Status\n';
output += '-'.repeat(70) + '\n';
if (Object.keys(data.domains).length > 0) {
Object.entries(data.domains).forEach(([domain, info]) => {
output += `${domain.padEnd(40)}${info.IP.padEnd(15)}${info.SSL.padEnd(5)}${info.SUSPENDED === 'no' ? 'Active' : 'Suspended'}\n`;
});
} else {
output += 'No domains found for this user\n';
}
pre.textContent = output;
} else {
pre.textContent = `❌ Error: ${data.message}\nDebug: ${data.debug || ''}\nJSON Error: ${data.json_error || ''}`;
}
})
.catch(error => {
document.getElementById('get-response').textContent = `❌ Fetch Error: ${error.message}`;
});
</script>
</Layout>

View File

@@ -2,8 +2,8 @@
import Layout from '../layouts/Layout.astro'; import Layout from '../layouts/Layout.astro';
// Page-specific SEO metadata // Page-specific SEO metadata
const pageTitle = "SiliconPin - Lets create some digital freedom"; const pageTitle = "SiliconPin - High-Performance Hosting Solutions";
const pageDescription = "SiliconPin - easy to deploy apps and tools, freedom oriented apps and tools, high-performance, hosting solutions for PHP, Node.js, Python, Kubernetes (K8s), and K3s, and technical support."; const pageDescription = "SiliconPin offers reliable, high-performance hosting solutions for PHP, Node.js, Python, Kubernetes (K8s), and K3s with 24/7 technical support.";
const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=80&w=2000&auto=format&fit=crop"; const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=80&w=2000&auto=format&fit=crop";
--- ---

View File

@@ -3,7 +3,7 @@ import Layout from '../layouts/Layout.astro';
// Page-specific SEO metadata // Page-specific SEO metadata
const pageTitle = "Legal Agreement | SiliconPin"; const pageTitle = "Legal Agreement | SiliconPin";
const pageDescription = "Review SiliconPin's legal agreement for using our services. Find information about your legal rights and obligations."; const pageDescription = "Review SiliconPin's legal agreement for using our hosting services. Find information about your legal rights and obligations.";
const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=80&w=2000&auto=format&fit=crop"; const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=80&w=2000&auto=format&fit=crop";
--- ---
@@ -23,20 +23,6 @@ const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=8
<div class="max-w-4xl mx-auto space-y-8"> <div class="max-w-4xl mx-auto space-y-8">
<section class="bg-neutral-800 rounded-lg p-6 sm:p-8 border border-neutral-700"> <section class="bg-neutral-800 rounded-lg p-6 sm:p-8 border border-neutral-700">
<h3 class="text-xl font-medium text-[#6d9e37]">TLDR;</h3>
<p class="text-neutral-300">
We are trying to create some digital freedom together. We avoid any vender locking - for you and us.
some of us from DWD Consultancy Services, having a quite experience manipulating data and data resilience.
Still we advise to keep a backup of your data periodically and use our automated backup and snapshot services (even AWS/GCP dont take data responsibility).
You are responsible for your content, and we are responsible for our services.
If something goes wrong, we will try to fix it. For SLA we will refund or we will part ways.
We are based in India, and Indian law applies to this agreement. We find some law funny and useless like the cookie acknowledgement.
<br>
we strongly feel just to be reasonable and fair to each other.
</p>
<hr>
<br>
<p class="text-neutral-300"> <p class="text-neutral-300">
This Legal Agreement ("Agreement") is a binding contract between you ("Customer" or "you") and SiliconPin ("Company", "we", or "us") governing your use of our hosting services and related products (collectively, the "Services"). By using our Services, you acknowledge that you have read, understood, and agree to be bound by this Agreement. This Legal Agreement ("Agreement") is a binding contract between you ("Customer" or "you") and SiliconPin ("Company", "we", or "us") governing your use of our hosting services and related products (collectively, the "Services"). By using our Services, you acknowledge that you have read, understood, and agree to be bound by this Agreement.
</p> </p>
@@ -182,7 +168,7 @@ const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=8
If you have any questions about this Legal Agreement, please contact us: If you have any questions about this Legal Agreement, please contact us:
</p> </p>
<div class="text-neutral-300"> <div class="text-neutral-300">
<p>Email: <a href="mailto:contact@siliconpin.com" class="text-[#6d9e37] hover:underline">contact@siliconpin.com</a></p> <p>Email: <a href="mailto:legal@siliconpin.com" class="text-[#6d9e37] hover:underline">legal@siliconpin.com</a></p>
<p>Phone: +91-700-160-1485</p> <p>Phone: +91-700-160-1485</p>
<p>Address: 121 Lalbari, GourBongo Road, Habra, W.B. 743271, India</p> <p>Address: 121 Lalbari, GourBongo Road, Habra, W.B. 743271, India</p>
</div> </div>

View File

@@ -1,19 +0,0 @@
---
import Layout from "../layouts/Layout.astro";
const phpHello = `$_SESSION['userName']`;
---
<Layout title="Profile Page">
<div class="flex items-center justify-center min-h-screen bg-gray-700">
<div class="w-96 p-6 shadow-lg rounded-lg bg-white text-center">
<img class="w-24 h-24 rounded-full border-4 border-blue-500 mx-auto" src="/profile.jpg" alt="Profile Picture" />
<h2 class="text-2xl font-semibold mt-4" set:html={phpHello ? phpHello : 'User Name'}></h2>
<p class="text-gray-600">Frontend Developer</p>
<p class="text-gray-500 text-sm mt-2">"Building amazing UI experiences one component at a time."</p>
<div class="flex justify-center space-x-4 mt-4">
<button class="bg-blue-500 text-white px-4 py-2 rounded-lg">Follow</button>
<button class="bg-gray-200 text-black px-4 py-2 rounded-lg">Message</button>
</div>
</div>
</div>
</Layout>